POJ 2983-Is the Information Reliable
Description
The galaxy war between the Empire Draco and the Commonwealth of Zibu broke out 3 years ago. Draco established a line of defense called Grot. Grot is a straight line with N defense stations. Because of the cooperation of the stations, Zibu’s Marine Glory cannot march any further but stay outside the line.
A mystery Information Group X benefits form selling information to both sides of the war. Today you the administrator of Zibu’s Intelligence Department got a piece of information about Grot’s defense stations’ arrangement from Information Group X. Your task is to determine whether the information is reliable.
The information consists of M tips. Each tip is either precise or vague.
Precise tip is in the form of P A B X
, means defense station A is X light-years north of defense station B.
Vague tip is in the form of V A B
, means defense station A is in the north of defense station B, at least 1 light-year, but the precise distance is unknown.
Input
There are several test cases in the input. Each test case starts with two integers N (0 < N ≤ 1000) and M (1 ≤ M ≤ 100000).The next M line each describe a tip, either in precise form or vague form.
Output
Output one line for each test case in the input. Output “Reliable” if It is possible to arrange N defense stations satisfying all the M tips, otherwise output “Unreliable”.
Sample Input
3 4
P 1 2 1
P 2 3 1
V 1 3
P 1 3 1
5 5
V 1 2
V 2 3
V 3 4
V 4 5
V 3 5
Sample Output
Unreliable
Reliable
Solution:
还是差分约束判断可行性。。。
我们依然罗列出约束条件(可行性我直接当做求最小值来做):
1、$s[v]-s[u]=c,s[u]-s[v]=c$,所以建边$w[u,v]=w[v,u]=c$(注意是双向的,因为等于是个对于两边都成立的约束条件)
2、$s[v]-s[u]>0$,即$s[v]-s[u]\geq 1$,所以建边$w[u,v]=1$
记得新建一个源点,连向各点$w[1,i]=0,\;i\in 1\rightarrow n$,以保证图联通。
然后跑一遍最长路,判断一下有无环输出就好了。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #pragma GCC optimize(2) #define il inline #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) using namespace std; const int N=300005,M=1005,inf=23333333; int h[M],to[N],net[N],w[N],cnt,dis[M],tot[M],n,m; bool vis[M]; il void add(int u,int v,int c){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,w[cnt]=c;} il void gi(int &a){ a=0;char x=getchar();bool f=0; while((x<'0'||x>'9')&&x!='-')x=getchar(); if(x=='-')x=getchar(),f=1; while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar(); } il bool spfa(){ queue<int>q; dis[0]=0;q.push(0);tot[0]++; while(!q.empty()){ int u=q.front();q.pop();vis[u]=0; for(int i=h[u];i;i=net[i]) if(dis[to[i]]<dis[u]+w[i]){ dis[to[i]]=dis[u]+w[i]; if(!vis[to[i]]){ if(++tot[to[i]]>n)return 0; q.push(to[i]),vis[to[i]]=1; } } } return 1; } int main(){ while(~scanf("%d%d",&n,&m)){ char s[5]; cnt=0; memset(dis,-0x3f,sizeof(int)*(n+3)); memset(vis,0,sizeof(int)*(n+3)); memset(tot,0,sizeof(int)*(n+3)); memset(h,0,sizeof(h)); int u,v,c; while(m--){ scanf("%s",s); gi(u),gi(v); if(s[0]=='P'){ gi(c); add(v,u,-c);add(u,v,c); } else add(u,v,1); } For(i,1,n) add(0,i,0); if(spfa())puts("Reliable"); else puts("Unreliable"); } return 0; }