洛谷 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;
}

❀完结撒花❀

posted @ 2020-08-08 21:13  LJC001151  阅读(149)  评论(0)    收藏  举报