●POJ 2983 Is the Information Reliable?

题链:

http://poj.org/problem?id=2983

题解:

差分约束。

1).对于条件(P u v w),不难发现反映到图上就是:

$dis[u]-dis[v]=w$,所以添加两条边:

u → v : -w

v → u : w

2).对于条件(V,u,v),反映到图上即为:

$dis[u]-dis[v]>=1$,所以添加一条边:

v → u : 1

建好图后,dfs版spfa判一下是否存在正环就好了。

(出现正环代表Unreliable,否则就是Reliable)

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 1050
#define MAXM 100050
using namespace std;
struct Edge{
	int to[MAXM*2],nxt[MAXM*2],val[MAXM*2],head[MAXN],ent;
	void Reset(){ent=2;memset(head,0,sizeof(head));}
	void Adde(int u,int v,int w){
		to[ent]=v; val[ent]=w; nxt[ent]=head[u]; head[u]=ent++;
	}
}E;
int dis[MAXN],mark[MAXN];
int N,M;
bool dfs(int u){
	if(mark[u]) return 1; mark[u]=1;
	for(int i=E.head[u];i;i=E.nxt[i]){
		if(dis[E.to[i]]>=dis[u]+E.val[i]) continue;
		dis[E.to[i]]=dis[u]+E.val[i];
		if(dfs(E.to[i])) return mark[u]=0,1;
	}
	return mark[u]=0,0;
}
bool check(){
	memset(dis,0,sizeof(dis));
	for(int i=1;i<=N;i++) if(dfs(i)) return 0;
	return 1;
}
int main(){
	char cmd; int u,v,w;
	while(~scanf("%d%d",&N,&M)){
		E.Reset();
		for(int i=1;i<=M;i++){
			scanf(" %c%d%d",&cmd,&u,&v);
			if(cmd=='P'){
				scanf("%d",&w);
				E.Adde(v,u,w);
				E.Adde(u,v,-w);
			}else E.Adde(v,u,1);
		}
		if(check()) printf("Reliable
");
		else printf("Unreliable
");
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zj75211/p/8365646.html