对于给定的等式关系,转化成<=与>=的关系,然后建边,推出大小关系,按一个方向排好,然后最长路或最短路,跑一遍就可以了。
这类题,倒是不难,就是看思维是否能想到了,,将两两之间的关系,转成图的两点之间路的关系
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
#define MAXN 2000
typedef long long ll;///差分约束
int f[MAXN],dis[MAXN],vis[MAXN],cont[MAXN];
int n,m;
char ch[2];
int u,v,w,num;
struct AA
{
int w,v,next;
}pos[300005];
void add(int u,int v,int w)
{
pos[++num].v=v;
pos[num].w=w;
pos[num].next=f[u];
f[u]=num;
}
int SPFA()
{
queue<int>q;
q.push(0);
vis[0]=1;
cont[0]=1;
dis[0]=0;
while(!q.empty())
{
int x=q.front();
if(cont[x]>n) return 0;
cont[x]++;
q.pop();
vis[x]=0;
for(int i=f[x];i!=-1;i=pos[i].next)
{
int v=pos[i].v;
if(dis[v]>dis[x]+pos[i].w) {
dis[v]=dis[x]+pos[i].w;
if(vis[v]==0)
{
q.push(v);
vis[v]=1;
}
}
}
}
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(f,-1,sizeof(f));
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(cont,0,sizeof(cont));
num=0;
while(m--)
{
scanf("%s",ch);
if(ch[0]=='P')
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,-w);
add(v,u,w);
}
else
{
scanf("%d%d",&u,&v);
add(u,v,-1);
}
}
for(int i=1;i<=n;i++) add(0,i,0);
if(SPFA()) printf("Reliable\n");
else printf("Unreliable\n");
}
}