poj1637 Sightseeing tour[最大流+欧拉回路]

混合图的欧拉回路定向问题。

顺便瞎说几句,有向图定欧拉回路的充要条件是每个点入度等于出度,并且图联通。无向图的话只要联通无奇点即可。

欧拉路径的确定应该是无向图联通且奇点数0个或2个,有向图忘了,好像复杂一点,这个真考到就暴力瞎搜吧。

既然每个点的度数都定了,又入度等于出度,那两者对半分,在二分图里左向右连上原图的边,左点集与s连容量为待补充的出度,右点集反之。这样如果我真可以定下来的话,就会有左边所有连边都满流。所以跑最大流看能不能到满流(就是差的总出度)即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 typedef long long ll;
 8 template<typename T>inline char MIN(T&A,T B){return A<B?A=B,1:0;}
 9 template<typename T>inline char MAX(T&A,T B){return A>B?A=B,1:0;}
10 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
11 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
12 template<typename T>inline T read(T&x){
13     x=0;char c;while(!isdigit(c=getchar()))if(isalpha(c))return x=(int)c;
14     while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();return x;
15 }
16 const int N=200+7,M=3000+7,INF=0x3f3f3f3f;
17 int w[M<<1],v[M<<1],Next[M<<1],Head[N<<1],cur[N<<1],dis[N<<1],tot,s,t,n,m;
18 inline void Addedge(int x,int y,int z){
19     v[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
20     v[++tot]=x,Next[tot]=Head[y],Head[y]=tot,w[tot]=0;
21 }
22 #define y v[j]
23 inline char bfs(){
24     queue<int> q;q.push(s),memset(dis,0,sizeof dis),dis[s]=1;
25     for(register int i=1;i<=(n<<1)+2;++i)cur[i]=Head[i];
26     while(!q.empty()){
27         int x=q.front();q.pop();
28         for(register int j=Head[x];j;j=Next[j])if(w[j]&&!dis[y]){
29             dis[y]=dis[x]+1,q.push(y);
30             if(y==t)return 1;
31         }
32     }
33     return 0;
34 }
35 int dinic(int x,int flow){
36     if(!flow||x==t)return flow;
37     int rest=flow,k;
38     for(register int j=cur[x];j&&rest;cur[x]=j,j=Next[j])if(w[j]&&dis[y]==dis[x]+1){
39         if(!(k=dinic(y,_min(rest,w[j]))))dis[y]=0;
40         rest-=k,w[j]-=k,w[j^1]+=k;
41     }
42     return flow-rest;
43 }
44 #undef y
45 int in[N],out[N],cnt[N];
46 int x,y,z,T,p,tmp,ans,sigma;
47 inline void inc(int x,int y){++out[x],++in[y];}
48 
49 int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
50     read(T);while(T--){
51         read(n),read(m);s=(n<<1)+1,t=(n<<1)+2,p=tot=1,sigma=ans=0;
52         memset(Head,0,sizeof Head),memset(in,0,sizeof in),memset(out,0,sizeof out),memset(cnt,0,sizeof cnt);
53         for(register int i=1;i<=m;++i){
54             read(x),read(y),read(z);if(x==y)continue;
55             z?inc(x,y):(Addedge(x,y+n,1),Addedge(y,x+n,1));++cnt[x],++cnt[y];
56         }
57         for(register int i=1;i<=n;++i)if(cnt[i]&1){
58             printf("impossible
");p=0;break;
59         }
60         else{
61             tmp=cnt[i]>>1;if(tmp<in[i]||tmp<out[i]){printf("impossible
");p=0;break;}
62             Addedge(s,i,tmp-out[i]),Addedge(i+n,t,tmp-in[i]),sigma+=tmp-out[i];
63         }
64         if(p){
65             while(bfs())ans+=dinic(s,INF);
66             if(ans==sigma)printf("possible
");
67             else printf("impossible
");
68         }
69     }
70     return 0;
71 }
原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10357930.html