poj 2983 Is the Information Reliable? (差分约束 spfa)
来源:互联网 发布:时时彩组号软件 编辑:程序博客网 时间:2024/05/17 02:40
/* 先不说什么。这个题目晦涩难懂,还有一种可能是我英语太渣了。 = = 差分约束条件题目的难点是“怎么找到问题的约束条件”。 输入边的信息有两种情况。P 和 V。 P i j b 表示 xi - xj = b >>>> xi - xj <= b && xi - xj >= b (即 xj - xi <= -b) V 表示边长不确定 xi - xj >= 1 >>>> xj - xi <= -1; 好了,列出方程后建图,spfa即可 先要建立一个源点,源点到其他顶点之间的距离全部是0,然后用spfa判断是否存在负环 */#include<iostream>#include<cstring>#include<queue>#include<cstdio>using namespace std;const int N = 1010;const int M = 100010;const int inf = 0x3f3f3f3f;typedef struct{ int next,w,e;} Node;Node edge[M*3];int head[1010];int inqueue[1010];bool vis[1010];int num_edge;int dis[1010];int n,m;void addedge(int u,int v,int w){ edge[num_edge].e = v; edge[num_edge].w = w; edge[num_edge].next = head[u]; head[u] = num_edge++;}bool spfa(int start)/*spfa 队列*/{ memset(vis,false,sizeof(vis)); memset(inqueue,0,sizeof(inqueue)); for(int i = 0 ; i <= n ; i++) { dis[i] = inf; } queue<int>q; vis[start] = true; q.push(start); dis[start] = 0; while(!q.empty()) { int cur = q.front(); q.pop(); vis[cur] = false; inqueue[cur]++; if(inqueue[cur] > n) { return false; } for(int i = head[cur] ; i != -1 ; i = edge[i].next) { int x = edge[i].e; if(dis[x] > dis[cur] + edge[i].w) { dis[x] = dis[cur] + edge[i].w; if(!vis[x]) { vis[x] = true; q.push(x); } } } } return true;}int main(){ while(scanf("%d %d",&n,&m) != EOF ) { memset(head,-1,sizeof(head)); num_edge = 0; char s[5]; int u,v,w; for(int i = 0 ; i < m ; i++) { scanf("%s",s); if(s[0] == 'P') { scanf("%d %d %d",&u,&v,&w); addedge(u,v,w); addedge(v,u,-w); } else if(s[0] == 'V') { scanf("%d %d",&u,&v); addedge(v,u,-1); } } for(int i = 1; i <= n ; i++) { addedge(0,i,0); } bool flag = spfa(0); if(flag ) { printf("Reliable\n"); } else { printf("Unreliable\n"); } } return 0;}