POJ 2983
POJ 2983 Is the information reliable?
SPFA+差分约束练习题。
注意事项:
P: //dis[a] - dis[b] = c;
//dis[a] - dis[b] <= c;
//dis[b] - dis[a] <= -c;
V: //dis[a] - dis[b] >= 1;
//dis[b] - dis[a] <= -1;
bellman-ford的话不用加超级源,但是SPFA要,因为给的图可能不连通。
deg表示入队的次数,网上有些代码将deg表示成松弛的次数,提交也过了,但是感觉是不对的(确实也很难构造出这样的数据)。
这是我的代码,可以作为SPFA模板
#include <cstdio> #include <cstring> #include <queue> #include <vector> using std::memset; using std::queue; using std::vector; const int MAX = 1005; const int INF = 99999999; int n,m; queue<int> q; struct edge { int to,v; edge(int _to,int _v) { to = _to; v = _v; } }; vector<edge> graph[MAX]; bool spfa() { int dis[MAX]; int vis[MAX]; int deg[MAX]; for(int i = 0; i < MAX; i++) dis[i] = INF; memset(vis,0,sizeof(vis)); memset(deg,0,sizeof(deg)); dis[0] = 0; q.push(0); deg[0]++; while(q.empty() == false) { int from = q.front(); q.pop(); vis[from] = false; for(int i = 0 ; i < graph[from].size(); i++) { int to = graph[from][i].to; int v = graph[from][i].v; if(dis[to] > dis[from] + v) { dis[to] = dis[from] + v; if(!vis[to]) { q.push(to); vis[to] = 1; deg[to]++; if(deg[to] >= n) return false; } } } } return true; } int main() { while(scanf("%d%d",&n, &m)!=EOF) { //init; for(int i = 0 ; i < MAX; i++) { graph[i].clear(); } while(!q.empty()) q.pop(); while(m--) { char op[2]; scanf("%s", op); if(op[0] == 'P') { int a,b,c; scanf("%d%d%d",&a,&b,&c); graph[a].push_back(edge(b,-c)); graph[b].push_back(edge(a,c)); //dis[a] - dis[b] = c; //dis[a] - dis[b] <= c; //dis[b] - dis[a] <= -c; } else { int a,b; scanf("%d%d",&a,&b); graph[a].push_back(edge(b,-1)); //dis[a] - dis[b] >= 1; //dis[b] - dis[a] <= -1; } } //super source; for(int i = 0 ; i <= n; i++) { graph[0].push_back(edge(i,0)); } if(spfa()) { printf("Reliable\n"); } else { printf("Unreliable\n"); } } }