题目大意:已知关于在一条直线上的n个点的m条信息,信息分为两类,
1、准确信息:P A B X 表示A在B的北方X光年;
2、模糊信息:V A B 表示A在B的北方1光年以北。
问所给信息是否自相矛盾?
比较裸的差分约束系统。
将等式转为2个不等式即可建立差分约束系统,另需添加一个源点。
使用memset时尽量计算需要清空的大小,否则容易被多组小数据卡到TLE。
View Code
#include#include #include using namespace std;#define N 1010#define M 500100#define INF 0x3fffffffint n,m,e;int first[N],next[M],v[M],w[M];int d[N],inq[N],cnt[N];void init(){ e=0; memset(first,-1,sizeof(int)*(n+5));}void insert(int a,int b,int c){ v[e]=b; w[e]=c; next[e]=first[a]; first[a]=e++;}void spfa(){ queue q; int a,b; bool loop=false; memset(inq,0,sizeof(int)*(n+5)); memset(cnt,0,sizeof(int)*(n+5)); for(int i=1;i<=n;i++) d[i]=INF; d[n+1]=0; inq[n+1]=1; cnt[n+1]++; q.push(n+1); while(!q.empty()) { a=q.front(),q.pop(); if(cnt[a]>n+1) { loop=true; break; } inq[a]=0; for(int i=first[a];i!=-1;i=next[i]) { b=v[i]; if(d[b]>d[a]+w[i]) { d[b]=d[a]+w[i]; if(!inq[b]) inq[b]=1,q.push(b),cnt[b]++; } } } if(loop) puts("Unreliable"); else puts("Reliable");}int main(){ int a,b,c; char ch; while(~scanf("%d%d",&n,&m)) { init(); while(m--) { ch=0; while(ch!='P' && ch!='V') scanf("%c",&ch); scanf("%d%d",&a,&b); if(ch=='P') { scanf("%d",&c); insert(a,b,-c); insert(b,a,c); } else insert(a,b,-1); } for(int i=1;i<=n;i++) insert(n+1,i,0); spfa(); } return 0;}