POJ-2983 Is the Information Reliable?
题目大意:
有n个点,有m个约束,有两种约束形式,一种是P A B C表示A在B的北边距离为C的地方,另外一种是V A B表示A在B的背边距离至少为1的地方,问你这个信息是否存在矛盾的地方
解题思路:
P A B C表示S[B] - S[A] = C
那么可以表示成C <= S[B] - S[A] <= C
这样就是差分约束的模板题了
代码:
#include <queue> #include <cstdio> #include <cstring> using namespace std; const int maxn = 1000 + 5; const int INF = 0x3f3f3f3f; typedef struct node{ int to, w; int next; node(int a = 0, int b = 0, int c = 0){ to = a; next = b; w = c; } }Edge; int tot; //int s[maxn * maxn]; Edge edge[maxn * maxn]; int head[maxn * maxn], dis[maxn], vis[maxn], cnt[maxn]; void add(int u, int v, int w){ edge[tot] = node(v, head[u], w); head[u] = tot++; } bool spfa(int n){ int u, v;// top = 0; queue<int> q; while(!q.empty()) q.pop(); for(int i = 0; i <= n; ++i){ dis[i] = INF; vis[i] = 0; cnt[i] = 0; } //s[top++] = 0; q.push(0); dis[0] = 0; vis[0] = 1; while(!q.empty()){ u = q.front(); q.pop(); vis[u] = 0; if((++cnt[u]) > n) return 0; for(int i = head[u]; ~i; i = edge[i].next){ v = edge[i].to; if(dis[v] > dis[u] + edge[i].w){ dis[v] = dis[u] + edge[i].w; if(!vis[v]){ vis[v] = 1; q.push(v); } } } } return 1; } int main(){ char op; int a, b, x, n, m; while(~scanf("%d%d", &n, &m)){ tot = 0; memset(head, -1, sizeof(head)); for(int i = 1; i <= n; ++i) add(0, i, 0); for(int i = 0; i < m; ++i){ scanf(" %c%d%d", &op, &a, &b); if(op == 'P'){ scanf("%d", &x); add(a, b, -x); add(b, a, x); }else add(a, b, -1); } if(spfa(n)) puts("Reliable"); else puts("Unreliable"); } return 0; }