日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

poj 1637(混合图求欧拉回路)

發布時間:2025/7/14 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj 1637(混合图求欧拉回路) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考博客:http://www.cnblogs.com/destinydesigner/archive/2009/09/28/1575674.html

1 定義

歐拉通路 (Euler tour)——通過圖中每條邊一次且僅一次,并且過每一頂點的通路。
歐拉回路 (Euler circuit)——通過圖中每條邊一次且僅一次,并且過每一頂點的回路。
歐拉圖——存在歐拉回路的圖。

2 無向圖是否具有歐拉通路或回路的判定

G有歐拉通路的充分必要條件為:G 連通,G中只有兩個奇度頂點(它們分別是歐拉通路的兩個端點)。
G有歐拉回路(G為歐拉圖):G連通,G中均為偶度頂點。

3 有向圖是否具有歐拉通路或回路的判定

D有歐拉通路:D連通,除兩個頂點外,其余頂點的入度均等于出度,這兩個特殊的頂點中,一個頂點的入度比出度大1,另一個頂點的入度比出度小1。
D有歐拉回路(D為歐拉圖):D連通,D中所有頂點的入度等于出度。

4 混合圖。混合圖也就是無向圖與有向圖的混合,即圖中的邊既有有向邊也有無向邊。

5 混合圖歐拉回路

混合圖歐拉回路用的是網絡流。
把該圖的無向邊隨便定向,計算每個點的入度和出度。如果有某個點出入度之差為奇數,那么肯定不存在歐拉回路。因為歐拉回路要求每點入度 = 出度,也就是總度數為偶數,存在奇數度點必不能有歐拉回路。
現在每個點入度和出度之差均為偶數。將這個偶數除以2,得x。即是說,對于每一個點,只要將x條邊反向(入>出就是變入,出>入就是變出),就能保證出 = 入。如果每個點都是出 = 入,那么很明顯,該圖就存在歐拉回路。
現在的問題就變成了:該改變哪些邊,可以讓每個點出 = 入?構造網絡流模型。有向邊不能改變方向,直接刪掉。開始已定向的無向邊,定的是什么向,就把網絡構建成什么樣,邊長容量上限1。另新建s和t。對于入 > 出的點u,連接邊(u, t)、容量為x,對于出 > 入的點v,連接邊(s, v),容量為x(注意對不同的點x不同。當初由于不小心,在這里錯了好幾次)。之后,察看是否有滿流的分配。有就是能有歐拉回路,沒有就是沒有。查看流值分配,將所有流量非 0(上限是1,流值不是0就是1)的邊反向,就能得到每點入度 = 出度的歐拉圖。
由于是滿流,所以每個入 > 出的點,都有x條邊進來,將這些進來的邊反向,OK,入 = 出了。對于出 > 入的點亦然。那么,沒和s、t連接的點怎么辦?和s連接的條件是出 > 入,和t連接的條件是入 > 出,那么這個既沒和s也沒和t連接的點,自然早在開始就已經滿足入 = 出了。那么在網絡流過程中,這些點屬于“中間點”。我們知道中間點流量不允許有累積的,這樣,進去多少就出來多少,反向之后,自然仍保持平衡。
所以,就這樣,混合圖歐拉回路問題,解了。

View Code 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define N 202 9 #define M 5005 10 #define inf 0x3f3f3f3f 11 queue<int> q; 12 struct edge{ 13 int to,next,c,f; 14 }e[M]; 15 int pre[N],level[N],in[N]; 16 int T,S,cnt; 17 void addedge(int u,int v,int c){ 18 e[cnt].f=0,e[cnt].to=v,e[cnt].c=c,e[cnt].next=pre[u],pre[u]=cnt++; 19 e[cnt].f=0,e[cnt].to=u,e[cnt].c=0,e[cnt].next=pre[v],pre[v]=cnt++; 20 } 21 bool dinic_bfs(){ 22 memset(level,0,sizeof(level)); 23 q.push(S); 24 level[S]=1; 25 while(!q.empty()){ 26 int u=q.front();q.pop(); 27 for(int edg=pre[u];edg!=0;edg=e[edg].next){ 28 int v=e[edg].to; 29 if(!level[v]&&e[edg].c>e[edg].f){ 30 level[v]=level[u]+1; 31 q.push(v); 32 } 33 } 34 } 35 return level[T]!=0; 36 } 37 int dinic_dfs(int u,int cp){ 38 int tmp=cp; 39 if(T==u)return cp; 40 for(int edg=pre[u];edg!=0&&tmp;edg=e[edg].next){ 41 int v=e[edg].to; 42 if(level[v]==level[u]+1&&e[edg].c>e[edg].f){ 43 int t=dinic_dfs(v,min(tmp,e[edg].c-e[edg].f)); 44 e[edg].f+=t; 45 e[edg^1].f-=t; 46 tmp-=t; 47 } 48 } 49 return cp-tmp; 50 } 51 bool dinic(int s){ 52 int tf=0,f=0; 53 while(dinic_bfs()){ 54 while(f=dinic_dfs(S,inf)){ 55 tf+=f; 56 } 57 } 58 59 return tf==s; 60 } 61 int main(){ 62 int ca; 63 scanf("%d",&ca); 64 while(ca--){ 65 int m,s,flag=1; 66 memset(pre,0,sizeof(pre)); 67 memset(in,0,sizeof(in)); 68 scanf("%d%d",&m,&s);S=0; 69 T=m+1;cnt=2; 70 while(s--){ 71 int u,v,c; 72 scanf("%d%d%d",&u,&v,&c); 73 in[u]--;in[v]++; 74 if(!c)addedge(u,v,1); 75 } 76 for(int i=1;i<=m;i++) 77 { 78 if(in[i]&1)flag=0; 79 } 80 int sum=0; 81 if(flag){ 82 for(int i=1;i<=m;i++){ 83 if(in[i]>0){addedge(i,T,in[i]>>1);sum+=in[i]>>1;} 84 if(in[i]<0)addedge(S,i,(-in[i])>>1); 85 } 86 } 87 if(!dinic(sum))flag=0; 88 if(!flag)printf("impossible\n"); 89 else printf("possible\n"); 90 } 91 return 0; 92 }

?

轉載于:https://www.cnblogs.com/huangriq/archive/2012/08/12/2634233.html

總結

以上是生活随笔為你收集整理的poj 1637(混合图求欧拉回路)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。