poj 1637 Sightseeing tour

题意:混合图求欧拉回路。

解法:对于欧拉图,所有顶点入度和出度之差均为偶数。

  建图思路:1.首先为无向边随意定一个方向,统计每个点入度出度;

       2.另设源点汇点,对于出度>入度的点,与源点连边,正向边容量为(out-in)/2,对于入度>出度的点,与汇点连边,正向边容量为(in-out)/2;

       3.对于除了源点汇点之外的点,有向边舍弃,无向边按照先前指定的方向建边,容量为1.

  整个图建好之后,流经每个顶点的容量可以理解成把这个点的入(出)边变成出(入)边的数量。。。

  如果是满流就表示所有的点最后都能使得入度==出度。。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #define N 1010
  6 #define M 10010
  7 using namespace std;
  8 const int inf=(1<<30);
  9 struct Edge{
 10     int u,v,c,next;
 11 }edge[M];
 12 int queue[N],stack[N],dis[N],head[N];
 13 int in[N],out[N];
 14 int cnt;
 15 void init(){
 16     memset(head,-1,sizeof(head));
 17     memset(in,0,sizeof(in));
 18     memset(out,0,sizeof(out));
 19     cnt=0;
 20 }
 21 void add(int u,int v,int c){
 22     edge[cnt].u=u;edge[cnt].v=v;edge[cnt].c=c;
 23     edge[cnt].next=head[u];head[u]=cnt++;
 24 }
 25 int dinic(int s,int t){
 26     int ans=0;
 27     while(1){
 28         int l,r,now,u,v,top;
 29         memset(dis,-1,sizeof(dis));
 30         l=r=0;
 31         queue[r++]=s;
 32         dis[s]=0;
 33         while(l<r){
 34             u=queue[l++];
 35             for(int k=head[u];k!=-1;k=edge[k].next){
 36                 u=edge[k].u;
 37                 v=edge[k].v;
 38                 if(edge[k].c>0&&dis[v]==-1){
 39                     dis[v]=dis[u]+1;
 40                     queue[r++]=v;
 41                     if(v==t){
 42                         l=r;
 43                         break;
 44                     }
 45                 }
 46             }
 47         }
 48         if(dis[t]==-1)break;
 49         now=s;
 50         top=0;
 51         while(1){
 52             if(now!=t){
 53                 int k;
 54                 for(k=head[now];k!=-1;k=edge[k].next){
 55                     if(edge[k].c>0&&dis[edge[k].v]==dis[edge[k].u]+1)break;
 56                 }
 57                 if(k!=-1){
 58                     stack[top++]=k;
 59                     now=edge[k].v;
 60                 }
 61                 else{
 62                     if(top==0)break;
 63                     dis[edge[stack[--top]].v]=-1;
 64                     now=edge[stack[top]].u;
 65                 }
 66             }
 67             else{
 68                 int flow=inf,w;
 69                 for(int i=0;i<top;i++){
 70                     if(flow>edge[stack[i]].c){
 71                         flow=edge[stack[i]].c;
 72                         w=i;
 73                     }
 74                 }
 75                 ans+=flow;
 76                 for(int i=0;i<top;i++){
 77                     edge[stack[i]].c-=flow;
 78                     edge[stack[i]^1].c+=flow;
 79                 }
 80                 now=edge[stack[w]].u;
 81                 top=w;
 82             }
 83         }
 84     }
 85     return ans;
 86 }
 87 int abs(int a,int b){
 88     return a>b?(a-b):(b-a);
 89 }
 90 int main(){
 91     int n,m,t;
 92     cin>>t;
 93     while(t--){
 94         cin>>n>>m;
 95         init();
 96         for(int i=1;i<=m;i++){
 97             int a,b,c;
 98             cin>>a>>b>>c;
 99             if(a==b)continue;
100             if(c==0){
101                 add(a,b,1);
102                 add(b,a,0);
103             }
104             in[b]++;
105             out[a]++;
106         }
107         bool flag=0;
108         for(int i=1;i<=n;i++){
109             if(abs(in[i]-out[i])&1){
110                 flag=1;
111                 break;
112             }
113         }
114         if(flag){
115             cout<<"impossible"<<endl;
116             continue;
117         }
118         int sum=0;
119         for(int i=1;i<=n;i++){
120             if(out[i]>in[i]){
121                 add(0,i,(out[i]-in[i])/2);
122                 add(i,0,0);
123                 sum+=(out[i]-in[i])/2;
124             }
125             else{
126                 add(i,n+1,(in[i]-out[i])/2);
127                 add(n+1,i,0);
128             }
129         }
130         int ans=dinic(0,n+1);
131         if(ans==sum)
132             cout<<"possible"<<endl;
133         else
134             cout<<"impossible"<<endl;
135     }
136     return 0;
137 }
posted @ 2012-11-15 23:57  silver__bullet  阅读(144)  评论(0编辑  收藏  举报