POJ - 1637 混合图欧拉回路

Sightseeing tour
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 10943 Accepted: 4598
Description

The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can see every corner of the beautiful city. They want to construct the tour so that every street in the city is visited exactly once. The bus should also start and end at the same junction. As in any city, the streets are either one-way or two-way, traffic rules that must be obeyed by the tour bus. Help the executive board and determine if it’s possible to construct a sightseeing tour under these constraints.
Input

On the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing two positive integers m and s, 1 <= m <= 200,1 <= s <= 1000 being the number of junctions and streets, respectively. The following s lines contain the streets. Each street is described with three integers, xi, yi, and di, 1 <= xi,yi <= m, 0 <= di <= 1, where xi and yi are the junctions connected by a street. If di=1, then the street is a one-way street (going from xi to yi), otherwise it’s a two-way street. You may assume that there exists a junction from where all other junctions can be reached.
Output

For each scenario, output one line containing the text “possible” or “impossible”, whether or not it’s possible to construct a sightseeing tour.
Sample Input

4
5 8
2 1 0
1 3 0
4 1 1
1 5 0
5 4 1
3 4 0
4 2 1
2 2 0
4 4
1 2 1
2 3 0
3 4 0
1 4 1
3 3
1 2 0
2 3 0
3 2 0
3 4
1 2 0
2 3 1
1 2 0
3 2 0
Sample Output

possible
impossible
impossible
possible


什么是混合图欧拉问题呢?
给你一张图,有有向边和无向边,你可以任意对无向边定向,问最后能不能成为欧拉回路。

然后可以利用求解最大流的方法求解:

将无向边的容量设为1,入度大于出度的点连接汇点,容量为di/2;出度大于入度的点连源点,容量也为di/2;有向边不建入图内。

这样如果结果满流,那么一定各点出度等于入度,存在欧拉回路。

怎么输出定向结果呢:如果要输出方案,我们把所有从x到y没有流量的边反向即可,该边流满,说明我们选择了这条边;该边未满,说明这条边需要反向。


AC代码:

#include<queue>
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=210,M=1e6+10;
int s,t,n,m,h[N],in[N],out[N],a[N*5],b[N*5],c[N*5],flag;
int head[N],nex[M],to[M],w[M],tot;
inline void ade(int a,int b,int c){
	to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
inline void add(int a,int b,int c){ade(a,b,c);	ade(b,a,0);}
inline int bfs(){
	queue<int> q;	memset(h,0,sizeof h);	h[s]=1;	q.push(s);
	while(q.size()){
		int u=q.front();	q.pop();
		for(int i=head[u];i;i=nex[i]){
			if(w[i]&&!h[to[i]]){
				h[to[i]]=h[u]+1;	q.push(to[i]);
			}
		} 
	}	
	return h[t];
}
int dfs(int x,int f){
	if(x==t)	return f;	int fl=0;
	for(int i=head[x];i&&f;i=nex[i]){
		if(w[i]&&h[to[i]]==h[x]+1){
			int mi=dfs(to[i],min(w[i],f));
			w[i]-=mi,w[i^1]+=mi,fl+=mi,f-=mi;
		}
	}
	if(!fl)	h[x]=-1;
	return fl;
}
inline int dinic(){
	int res=0;
	while(bfs())	res+=dfs(s,inf);
	return res;
}
inline void init(){
	tot=1,flag=0;	memset(head,0,sizeof head);
	memset(in,0,sizeof in),memset(out,0,sizeof out);
}
inline void solve(){
	init();	cin>>n>>m;	t=n+1;
	for(int i=1;i<=m;i++){
		scanf("%d %d %d",&a[i],&b[i],&c[i]);
		out[a[i]]++,in[b[i]]++;
	}
	for(int i=1;i<=n&&!flag;i++)	if((in[i]+out[i])%2)	flag=1;
	if(flag){puts("impossible");	return ;}
	for(int i=1;i<=m;i++)	if(!c[i])	add(a[i],b[i],1);
	int sum=0;
	for(int i=1;i<=n;i++){
		if(in[i]>out[i])	add(i,t,(in[i]-out[i])/2),sum+=(in[i]-out[i])/2;
		else if(in[i]<out[i])	add(s,i,(out[i]-in[i])/2);
	}
	if(dinic()==sum)	puts("possible");
	else	puts("impossible");
}
int main(){
	int T;	cin>>T;
	while(T--)	solve();
	return 0;
}
发布了489 篇原创文章 · 获赞 241 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104107829
今日推荐