洛谷P1260 工程规划

差分约束,反向连边,判负环,然后因为可能存在负值,就减去dis最小的,也保证了题目中至少一个为0的要求

代码

//By AcerMo
#include
#include
#include
#include
#include
#include
using namespace std;
const int M=100500;
int n,m;
int dis[M],vis[M],ti[M];
int to[M],w[M],nxt[M],head[M],cnt;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch>'9'||ch<'0') {if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
inline void add(int x,int y,int z)
{
	to[++cnt]=y;w[cnt]=z;nxt[cnt]=head[x];head[x]=cnt;
	return ;	
} 
inline void SPFA(int i)
{
	queueq;q.push(i);
	dis[i]=0;ti[i]++;
	while (q.size())
	{
		int u=q.front();q.pop();vis[u]=0;
		for (int i=head[u];i;i=nxt[i])
		{
			if (dis[to[i]]>dis[u]+w[i])
			{
				dis[to[i]]=dis[u]+w[i];ti[to[i]]++;
				if (ti[to[i]]>n) {puts("NO SOLUTION");exit(0);}
				if (!vis[to[i]]) 
					vis[to[i]]=1,q.push(to[i]);
			}
		}
	}
	return ;
}
signed main()
{
	n=read();m=read();int x,y,z;
	for (int i=1;i<=m;i++)
		x=read(),y=read(),z=read(),add(y,x,z);
	fill(dis,dis+n+1,1e9);
	for (int i=1;i<=n;i++)
	if (ti[i]==0) SPFA(i);
	int mini=1e9;
	for (int i=1;i<=n;i++) mini=min(mini,dis[i]);
	for (int i=1;i<=n;i++) cout<

 

你可能感兴趣的:(图论-差分约束)