想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:给出n个点m个约束
如果约束是P a b c的形式就代表,a在b北边的c的位置
如果约束是V a b 的形式就代表,a在b北边1或者更远的位置。
解题思路:很明显,我们由题目可以得到不等式
首先设d[i]为从初始点到i点的距离
V a b ----> d[a]-d[b]>=1
P a b c ----> d[a]-d[b]==c
那么根据上两个式子分析,再得到:
V:d[b]-d[a]<=-1
P:d[a]-d[b]<=c 因为等号可以化成两个不等式
d[a]-d[b]>=c
这样最后得到:
V:d[b]-d[a]<=-1
P:d[a]-d[b]<=c
d[b]-d[a]<=-c
这样根据约束用bellman_ford直接可以做,不过spfa还有点不一样
如果用spfa的话,所有的点不一定会互相连通的,这样我们设一个虚点(随便什么点)与其他所有点相连,不过长度为0
for(i=1;i<=n;i++) add(s,i,0);
这个地方不要看成了是不等式,他只是消掉了自身的负环而已
当然这里我设s为0,为其他的也可以
/*
spfa
Memory 2564K
Time 610MS
*/
#include <iostream>
#include <queue>
using namespace std;
#define MAXE 250000
#define MAXV 1010
#define INF INT_MAX
typedef struct{
int t,w,next;
}Edge;
Edge edge[MAXE];
int n,m,edgesum,d[MAXV];
int headlist[MAXV],sum[MAXV];
bool vis[MAXV];
void add(int s,int t,int w){
edge[edgesum].t=t;
edge[edgesum].next=headlist[s];
edge[edgesum].w=w;
headlist[s]=edgesum++;
}
bool spfa(){
queue <int>q;
int i,v,u;
memset(sum,0,sizeof(sum));
memset(vis,false,sizeof(vis));
for(i=1;i<=n;i++) d[i]=INF;
d[0]=0;
vis[0]=true;
q.push(0);
while(!q.empty()){
v=q.front();q.pop();
vis[v]=false;
if(++sum[v]>n) return 0; //有负环返回false
for(i=headlist[v];i!=-1;i=edge[i].next){
u=edge[i].t;
if(d[v]+edge[i].w<d[u]){
d[u]=d[v]+edge[i].w;
if(!vis[u]){
q.push(u);
vis[u]=true;
}
}
}
}
return 1;
}
int main(){
int i,a,b,c;
char ch;
while(~scanf("%d%d\n",&n,&m)){
edgesum=0;
memset(headlist,-1,sizeof(headlist));
for(i=0;i<m;i++){
scanf("%c%d%d",&ch,&a,&b);
if(ch=='P'){
scanf("%d",&c);
add(a,b,-c);
add(b,a,c);
}else{
add(a,b,-1);
}
getchar();
}
for(i=1;i<=n;i++) add(0,i,0); //消掉自身的负环
if(spfa()) printf("Reliable\n");
else printf("Unreliable\n");
}
return 0;
}
===========================================================
/*
bellman_ford
Memory 2516K
Time 454MS
*/
#include <iostream>
using namespace std;
#define MAXE 200000
#define MAXV 1010
typedef struct{
int s,t,w;
}Edge;
Edge edge[MAXE];
int n,m,edgesum,d[MAXV];
void add(int s,int t,int w){
edge[edgesum].s=s;
edge[edgesum].t=t;
edge[edgesum++].w=w;
}
bool bellman_ford(){
int j,cnt=0;
memset(d,0,sizeof(d));
bool flag=true;
while(flag && cnt<=n){
flag=false;
cnt++;
for(j=0;j<edgesum;j++)
if(d[edge[j].s]+edge[j].w<d[edge[j].t]){
d[edge[j].t]=d[edge[j].s]+edge[j].w;
flag=true;
}
}
if(cnt<n) return 1;
return 0;
}
int main(){
int i,a,b,c;
char ch;
while(~scanf("%d%d\n",&n,&m)){
edgesum=0;
for(i=0;i<m;i++){
scanf("%c%d%d",&ch,&a,&b);
if(ch=='P'){
scanf("%d",&c);
add(a,b,-c);
add(b,a,c);
}else{
add(a,b,-1);
}
getchar();
}
if(bellman_ford()) printf("Reliable\n");
else printf("Unreliable\n");
}
return 0;
}