poj 2983 Is the Information Reliable?(差分约束)

难点在于如何建立差分约束系统。

P:A-B=C<=>A-B<=c&&B-A<=-c

V:A-B>=1<=>B-A<=-1

这样就可以建立<=的差分约束系统,然后用bellman或者spfa判断负环就可以了。

#include<iostream>
#include<cstdio>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=1010;
int n,m,e;
int dis[maxn];

void init(){
	e=0;
	memset(dis,INF,sizeof(dis));
}

struct node{
	int u;
	int v;
	int w;
}edge[maxn*200];

void addEdge(int u,int v,int w){
	edge[e].u=u,edge[e].v=v,edge[e].w=w;
	e++;
}

bool relax(int x){
	if(dis[edge[x].v]>dis[edge[x].u]+edge[x].w){
		dis[edge[x].v]=dis[edge[x].u]+edge[x].w;
		return true;
	}
	return false;
}

bool Bellman_Ford(){
	dis[1]=0;
	for(int i=1;i<=n;i++){
		bool flag=false;
		for(int j=0;j<e;j++){
			if(relax(j))
				flag=true;
		}
		if(!flag) break;
	}
	for(int j=0;j<e;j++){
		if(relax(j)){
			return false;
		}
	}
	return true;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
#endif
    while(~scanf("%d%d",&n,&m)){
    	init();
    	char ch;
    	int a,b,c;
    	while(m--){
    		getchar();
    		scanf("%c",&ch);
    		if(ch=='P'){
    			scanf("%d%d%d",&a,&b,&c);
    			addEdge(a,b,c);
    			addEdge(b,a,-c);
    		}
    		else{
    			scanf("%d%d",&a,&b);
    			addEdge(b,a,-1);
    		}
    	}
    	bool flag=Bellman_Ford();
    	if(flag) puts("Reliable");
    	else puts("Unreliable");
    }
    return 0;
}


你可能感兴趣的:(poj 2983 Is the Information Reliable?(差分约束))