洛谷 P6145 【[USACO20FEB]Timeline G】
这道题貌似可以用拓扑做。
但是我不会。
于是就有了差分约束的做法。
不清楚差分约束的,建议去看看这道模板题,还有这道,都是差分约束的模板。
好,我们假设您已经 \(A\) 了上述两题(中的一题),那么,再看看这道题。
是不是觉得很水呢。
\(1.\) 第 \(i\) 次挤奶不早于 \(S_i\) 天进行。那么就让它在第 \(S_i\) 天进行。
\(2.\) 第 \(b\) 次挤奶在第 \(a\) 次后至少 \(x\) 天进行,那么就让它在后 \(x\) 天进行。
要实现 \(1.\) 的建图,需要建一个超级源点 \(s\) 。
因为题目保证有解(保证 Bessie 的记忆没有错误,这意味着一定存在一种合法的方案),所以可以放心的跑最长路,不用判断正环。
于是就是代码(队列是手写的)。
#include<bits/stdc++.h>
#define FOR(i,j,k) for(int i=(j);i<=(k);i++)
using namespace std;
int n,m,c,s,cnt;
int h[100010],t[200001],nxt[200001],val[200001];
int dis[100010];
bool inq[100010];
int f,e,q[100010001];
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}//快读
inline void addedge(int a,int b,int c)
{
t[++cnt]=b,val[cnt]=c,nxt[cnt]=h[a],h[a]=cnt;
}
inline void spfa()
{
while(f<=e)
{
int u=q[f++];
for(int p=h[u];p;p=nxt[p])
{
int v=t[p];
if(dis[v]<dis[u]+val[p])
{
dis[v]=dis[u]+val[p];
if(!inq[v]) inq[v]=true,q[++e]=v;
}
}
inq[u]=false;
}
return ;
}
int main()
{
memset(dis,-1,sizeof(dis));
n=read(),m=read(),c=read(),s=n+1;
for(int i=1;i<=n;i++)
{
int x=read();
addedge(s,i,x); //超级源点
}
for(int i=1;i<=c;i++)
{
int u=read(),v=read(),w=read();
addedge(u,v,w);
}
dis[s]=0,f=e=1,q[1]=s,inq[s]=true;
spfa();
for(int i=1;i<=n;i++)
printf("%d\n",dis[i]);
return 0;
}
❀完结撒花❀

浙公网安备 33010602011771号