看了几天的差分约束,看懂的时候又发现自己走了弯路Orz
如果是第一次学习差分约束的话,建议在学会至少一个最短路算法的前提下去理解了单个不等式怎么转化成最短路的
具体的这个链接讲的特别好,我就不献丑了
要是能在脑海里动态的把不等式转化为一个有向路就更好了
#include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; #define Edg pair<int,int> const int maxn = 1123; queue<int>Q; vector<Edg > edge[maxn]; void init(int n){ for(int i=0;i<=n;i++){ edge[i].clear(); } } void Link(int st,int ed,int v){ edge[st].push_back(Edg(ed,v)); } int cnt[maxn]; int dis[maxn]; bool inq[maxn]; bool haver[maxn]; bool vis[maxn]; bool spfa(int st,int n){ memset(cnt,0,sizeof(cnt)); memset(dis,0x3f,sizeof(dis)); memset(inq,0,sizeof(inq)); Q.push(st); cnt[st]++; dis[st] = 0; inq[st] = true; while(Q.empty()==false){ st = Q.front(); Q.pop(); vis[st] = true; inq[st] = false; for(vector<Edg >::iterator it = edge[st].begin();it!=edge[st].end();it++){ int ed = it->first; int v = it->second; if(dis[st] + v < dis[ed]){ dis[ed] = dis[st] + v; if(inq[ed] == false){ inq[ed] = true; cnt[ed]++; if(cnt[ed] > n) return false; Q.push(ed); } } } } return true; } bool jud(int n){ memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++){ if(vis[i]==false && spfa(i,n)==false) return false; } return true; } int main(){ int n,m; while(~scanf("%d %d",&n,&m)){ init(n); char typ[4]; int u,v,x; while(m--){ scanf("%s %d %d",typ,&u,&v); if(*typ == 'P'){ scanf("%d",&x); Link(u,v,x); Link(v,u,-x); } else{ Link(v,u,-1); } } if(jud(n)) puts("Reliable"); else puts("Unreliable"); // for(int i=1;i<=n;i++){ // printf(i<n?"%d ":"%d\n",dis[i]); // } } return 0; }