Sightseeing tour--POJ 1637

1、题目类型:图论、混合图欧拉回路、Edmonds_Karp算法。

2、解题思路:(1)将图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路;(2)构建流网络模型,Edmonds_Karp算法,察看是否有满流的分配。存在即有欧拉回路,没有就是没有欧拉回路。

3、注意事项:Edmonds_Karp算法中残留网络的更新。

4、参考博客:http://blog.csdn.net/bobten2008/archive/2009/11/11/4800084.aspx

5、实现方法:

#include<iostream>
#include
<cmath>
#include
<queue>
using namespace std;
#define Max 210
#define INF 99999999

int m,s,cnt;
int pre[Max],degree[Max];
int map[Max][Max],flag[Max][Max];
bool vis[Max];
queue
<int> Q;

int BFS()
{
int i,tmp,min,tmppre;
for(i=0;i<=m+1;i++)
{
vis[i]
=false;
pre[i]
=-1;
}
vis[
0]=true;
while(!Q.empty())
Q.pop();
Q.push(
0);
while(!Q.empty())
{
tmp
=Q.front();
Q.pop();
for(i=1;i<=m+1;i++)
{
if(i==tmp || vis[i] || !map[tmp][i])
continue;
vis[i]
=true;
pre[i]
=tmp;
Q.push(i);
}
}
if(pre[m+1]==-1)
return -1;
min
=INF,tmp=m+1;
while((tmppre=pre[tmp]) != -1)
{
if(map[tmppre][tmp]<min)
min
=map[tmppre][tmp];
tmp
=tmppre;
}
return min;
}

bool Edmonds_Karp(int cnt)
{
int i,tmp,val,tmppre,total;
while((val=BFS()) !=-1)
{
tmp
=m+1;
while((tmppre=pre[tmp]) != -1)
{
map[tmppre][tmp]
-=val;
map[tmp][tmppre]
+=val;
flag[tmppre][tmp]
+=val;
flag[tmp][tmppre]
=-flag[tmppre][tmp];
tmp
=tmppre;
}
}
total
=0;
for(i=1;i<=m;i++)
total
+=flag[0][i];
return total==cnt;
}
int main()
{
int i,n,start,end,type;
bool mark;
cin
>>n;
while(n--)
{
cin
>>m>>s;
mark
=true;
memset(degree,
0,sizeof(degree));
memset(map,
0,sizeof(map));
memset(flag,
0,sizeof(flag));
for(i=0;i<s;i++)
{
cin
>>start>>end>>type;
degree[start]
++;
degree[end]
--;
if(type!=1)
map[start][end]
++;
}
for(i=1;i<=m;i++)
{
if(abs(degree[i])%2==1)
{
mark
=false;
break;
}
else
degree[i]
=degree[i]/2;
}
if(mark)
{
cnt
=0;
for(i=1;i<=m;i++)
{
if(degree[i]<0)
map[i][m
+1]=abs(degree[i]);
else if(degree[i]>0)
{
map[
0][i]=degree[i];
cnt
+=degree[i];
}
}
if(!Edmonds_Karp(cnt))
mark
=false;
}
if(mark)
cout
<<"possible"<<endl;
else
cout
<<"impossible"<<endl;
}
return 1;
}

 

posted @ 2010-08-12 20:16  勇泽  阅读(490)  评论(0编辑  收藏  举报