题目链接:http://poj.org/problem?id=2983
大意:
有n个防卫站,其中有m个关系,这些关系又分为两种;
1、P,a,b,x表示a和b相距x光年;
2、V,a,b表示a和b相距至少1光年;
差分约束系统的建立:
第一种关系:
建立双向边,关系为
dist[a]-dist[b]>=x && dist[a]-dist[b <=x
=> dist[b]<=dist[a]- x && dist[a]<=dist[b]+x
第二种关系则为
dist[a]-dist[b] >=1
=>dist[b]<=dist[a]-1
判断图中是否存在负权环即为题目所求。
#include<iostream>
using namespace std;
class Edge
{
public:
int a;
int b;
int w;
}edge[200001];
int n,m;
int edge_num;
int dist[1001];
bool bellman_ford()
{
int i,j,k;
bool flag;
memset(dist,0,sizeof(dist));
for(i=0;i<n;i++)
{
flag=false;
for(j=0;j<edge_num;j++)
{
if(dist[ edge[j].b ]>dist[ edge[j].a ]-edge[j].w)
{
dist[ edge[j].b ]=dist[ edge[j].a ]-edge[j].w;
flag=true;
}
}
if(!flag)
break;
}
for(j=0;j<edge_num;j++)
{
if(dist[ edge[j].b ]>dist[ edge[j].a ]-edge[j].w)
return false;
}
return true;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
char temp;
int a,b,w;
edge_num=0;
for(int i=0;i<m;i++)
{
getchar();
scanf("%c",&temp);
if(temp=='P')
{
scanf("%d %d %d",&a,&b,&w);
edge[edge_num].a=a;
edge[edge_num].b=b;
edge[edge_num++].w=w; //对应关系dist[b]<=dist[a]-x
edge[edge_num].a=b;
edge[edge_num].b=a;
edge[edge_num++].w=-w; //对应关系dist[a]<=dist[b]+x
}
else if(temp=='V')
{
scanf("%d %d",&a,&b);
edge[edge_num].a=a;
edge[edge_num].b=b;
edge[edge_num++].w=1; //对应关系dist[b]<=dist[a]-1
}
}
if(bellman_ford())
printf("Reliable\n");
else
printf("Unreliable\n");
}
return 0;
}