一天一道题。。。今天写解题报告,明天回顾。。。
题目链接:http://poj.org/problem?id=2983
第一道差分约束题啊。。。
题意:有N个车站,给出一些点的精确信息和模糊信息,精确信息给出两点的位置和距离,模糊信息给出两点的位置,但距离大于等于一。试确定是否所有的信息满足条件
对于精确信息,可以得出两个差分条件,b-a = c;可以化为b <=a+c && a <= b-c;
对于模糊信息,只能得出一个差分条件,可以化为 b - a <= 1;所以a <= b-1;说明b到a有一条长度为-1的边
以上不等式都是在输入时处理的。。。
这就化成了:差分约束形式(题意表述参考别人的)。。。
Bellman_ford算法参考我博客另一篇文章:http://blog.csdn.net/bill_ming/article/details/7628435
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
const int M = 200010; //开100010竟然RE,一气之下开大点
const int INF = 999999;
struct Node
{
int u;
int v;
int w;
} p[M];
int dis[M];
int n,m;
int num;
bool Bellman_ford() //普通的Bellman_ford算法
{
for(int i = 1; i <= n; i++)
dis[i] = INF;
bool flag ;
for(int i = 1; i <= n; i++)
{
flag = false;
for(int j = 1; j <= num; j++)
{
if(dis[p[j].v] > dis[p[j].u] + p[j].w)
{
dis[p[j].v] = dis[p[j].u] + p[j].w;
flag = true;
}
}
if( !flag )
break;
}
for(int j = 1; j <= num; j++)
if(dis[p[j].v] > dis[p[j].u] + p[j].w)
return true;
return false;
}
int main()
{
char ch;
int a,b,c;
while(cin >> n >> m)
{
num = 0;
memset(dis,0,sizeof(dis));
for(int i = 1; i <= m; i++)
{
cin >> ch;
if(ch == 'P')
{
++num;
cin >> a >> b >> c; //根据不等式做输入处理
p[num].u = a;
p[num].v = b;
p[num].w = c;
++num;
p[num].u = b;
p[num].v = a;
p[num].w = -c;
}
else
{
++num;
cin >> a>>b;
p[num].u = b;
p[num].v = a;
p[num].w = -1;
}
}
if( Bellman_ford() )
{
cout << "Unreliable"<<endl;
}
else
{
cout << "Reliable"<<endl;
}
}
return 0;
}