(1)题意:
有两种信息,
P A B X表示A在B点的北边的准确距离为X
V A B表示A在B的北边,但是具体的距离不确定,但是距离一定大于1.
询问是否存在一种情况使N个据点满足之前的条件。
(2)思路:
建立一个图,源点为n+1,建图求最长路,如果图中存在正环,结果不可信,
否则可信。
建立关系如下:
P B-A>=x, A-B>=-x
V A-B>=1
然后判断是否存在正环即可。
(3)代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1024;
const int INF = 1e9+10;
const int maxm = 1e5+10;
int head[maxn],vis[maxn],dis[maxn],tim[maxn],tot,n,m,st[maxm];
struct Node{
int v,nxt,w;
}cur[maxm<<2];
void Init(){
memset(head,-1,sizeof(head));
tot = 0;
}
void Add(int x,int y,int z){
cur[tot] = Node{y,head[x],z};
head[x] = tot++;
}
bool spfa(int pos){
for(int i=0;i<=pos;i++){
dis[i] = -INF;tim[i] = 0;vis[i] = 0;
}
int top = 0;
st[top++] = pos;dis[pos] = 0;tim[pos]++;
while(top!=0){
int x = st[--top];vis[x] = 0;
for(int i=head[x];i!=-1;i=cur[i].nxt){
int y = cur[i].v;
if(dis[y]<dis[x]+cur[i].w){
dis[y] = dis[x]+cur[i].w;
if(vis[y]==0){
vis[y] = 1;
st[top++] = y;
if(++tim[y]>n+2) return false;
}
}
}
}
return true;
}
int main(void){
while(~scanf("%d%d",&n,&m)){
Init();
for(int i=0;i<m;i++){
char ss[5];
scanf("%s",ss);
if(ss[0]=='P'){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
Add(x,y,-z);
Add(y,x,z);
}
else{
int x,y;scanf("%d%d",&x,&y);
Add(y,x,1);
}
}
int pos = n+1;
for(int i=0;i<=n;i++) Add(pos,i,0);
if(spfa(pos)==true) printf("Reliable\n");
else printf("Unreliable\n");
}
return 0;
}