hdu 3592 World Exhibition //差分约束

#include "iostream"
#include "cstdio"
#include "cstring"
#include "queue"
#include "algorithm"
using namespace std;
#define mem(a,y) memset(a,y,sizeof(a))
#define inf 0x7f7f7f7f
const int maxn =  1100;
const int maxm = 30000;
struct node{
	int v,len,next;
}edge[maxm];
int head[maxn],dis[maxn],vis[maxn],Count[maxn];
int id,n;
void add_edge(int u,int v,int len){
	edge[id].v = v;edge[id].len = len;edge[id].next = head[u];head[u] = id++;
}
void init(int x,int y){
	
	int u,v,len;
	memset(head,-1,sizeof(head));id = 0;
	while( x -- ){
		//a[u] - a[v] < len
		scanf("%d %d %d",&u,&v,&len);
		add_edge(u,v,len);
	}
	while(y --){
		//a[u] - a[v] > len
		scanf("%d %d %d",&v,&u,&len);
		add_edge(u,v,-len);
	}
}
int spfa(){
	//当存在负环的时候,返回-1,当1到n没有路径时,返回-2,否则返回1到n最短距离
	mem(dis,inf);
	mem(vis,0);
	mem(Count,0);
	dis[1] = 0;vis[1] = 1;
	queue<int>que;
	que.push(1);
	while( !que.empty()){
		int u = que.front();que.pop();vis[u] = 0;
		for(int id = head[u]; id != -1; id = edge[id].next){
			int v = edge[id].v;
			if( dis[v] - edge[id].len > dis[u]){
				dis[v] = dis[u] + edge[id].len;
				if(!vis[v]){
					if( ++Count[v] > n)return -1;//单一个点入队列超过n次,说明存在负环
					vis[v] = 1;que.push(v);
				}
			}
		}
	}
	if( dis[n] == inf)dis[n] = -2;
	return dis[n];
}
int main(){
	int t,x,y;
	scanf("%d",&t);
	while( t-- ){
		scanf("%d %d %d",&n,&x,&y);
		init(x,y);
		printf("%d
",spfa());
	}
	return 0;
}
原文地址:https://www.cnblogs.com/LUO257316/p/3347737.html