UVA 10735 最大流 混合尤拉迴路 輸出路徑

2021-06-16 23:33:47 字數 3015 閱讀 2039

分類: uva && la

圖論 2013-07-21 11:13

125人閱讀收藏 

舉報題意:

給你乙個圖,有n個點,m條邊,有單向邊和雙向邊

讓你是否存在尤拉迴路,有就輸出路徑

1.判斷是否有尤拉迴路: 可以用最大流來判斷

首先,我們從結論出發: 存在尤拉迴路的充要條件是    每個點的入度等於出度。

先把所用無向邊隨便定向(我們就按輸入的時候的方向定向),

問題就轉化成  「改變其中一些無向邊的方向,使所有的點入度等於出度」。

對於改變某一條無向邊, 這條邊所在的點的度數改變2(可能-2, 可能+2)。

所以有如果有某個點出入度之差為奇數,那麼肯定不存在尤拉迴路(情況1)

記出入度之差為d

接下來討論除情況1以外的情況:

現在,每個點入度和出度之差均為偶數。

對於每個點,我們需要改變跟該點相連的x/2條邊, 就可以使該點的入度等於出度

新建源點s和匯點t

對於d < 0 的點i, 連s---->i , 流量為-d

對於d > 0 的點i, 連i----->t,流量為d

對於每條無向邊

,連i----->j, 流量為2   

流一遍最大流,如果對於所有的點i,存在s----->i的邊並且漫流,那麼尤拉迴路就有解。

2.輸出尤拉迴路: dfs+棧儲存

通過最大流以後,我們檢查無向邊流過的流量,我們可以確定無向邊的方向

然後問題就變為  "輸出無向圖的尤拉迴路"。

我們用dfs搜尋,訪問每條邊,對於節點u,當其u以下的兒子節點都搜過時,我們把u入棧

把棧反向輸出,就是我們要的尤拉迴路。

[cpp]view plain

copy

#include 

#include 

#include 

#include 

#include 

using

namespace

std;  

#define pii pair

#define mp make_pair

#define x first

#define y second

const

intmaxn = 510;  

const

intinf = 1e9;  

struct

edge  edge[maxn * maxn << 1];  

inte, head[maxn];  

intn, m;  

ints, t;  

vectoredges[maxn];  

void

add(

ints, 

intt, 

intc)   

intst[maxn], top;  

void

init()   

intgap[maxn], dis[maxn], pre[maxn], cur[maxn];  

intsap(

ints, 

intt, 

intn) 

// s 源點,t匯點,n頂點總數

gap[0] = n;  

intu = pre[s] = s, maxf = 0, aug = inf, v;  

while

(dis[s] < n)   

maxf += aug;  

aug = inf;  

}  goto

loop;  

}  }  

intmin_d = n;  

for(i = head[u]; i != -1; i = edge[i].next)   

}  if

(!(--gap[dis[u]]))  

break

;  ++gap[dis[u] = min_d + 1];  

u = pre[u];  

}  return

maxf;  

}  char

buf[3];  

intd[103];  

intx, y;  

bool

vis[maxn];  

void

dfs(

intu)   

st[top++] = u + 1;  

}  int

id;  

intmain()   

top = 0;  

memset(vis, 0, sizeof

(vis));  

id = 0;  

for(i = 0; i < m; i++)  else

}  for(i = 0; i < n; i++)  

if(d[i] & 1)  

break

;  if

(i != n)   

s = n;  

t = n + 1;  

for(i = 0; i < n; i++)   

intsum = sap(s, t, t + 1);  

for(i = head[s]; ~i; i = edge[i].next)  

if(edge[i].c)  

break

;  if

(~i)   

for(i = 0; i < n; i++)  

for(j = head[i]; ~j; j = edge[j].next)  

if(edge[j].op)  else

edges[i].push_back(mp(v, id++));  

}  dfs(0);  

for(i = top - 1; i >= 1; i--)  

printf("%d "

, st[i]);  

printf("%d\n\n"

, st[0]);  

}  return

0;  

}  

POJ 1637(最大流)混合尤拉迴路

1 定義 尤拉通路 euler tour 通過圖中每條邊一次且僅一次,並且過每一頂點的通路。尤拉迴路 euler circuit 通過圖中每條邊一次且僅一次,並且過每一頂點的迴路。尤拉圖 存在尤拉迴路的圖。2 無向圖是否具有尤拉通路或迴路的判定 g有尤拉通路的充分必要條件為 g 連通,g中只有兩個奇...

UVA 753(最大流匹配)

s 往m個裝置流1,然後每個裝置往對應插口號流1,然後插口號之間的k個轉換邊流無窮大 代表該裝備能被利用無窮遍 然後插排號流1到對應的n個插排,然後每個插排流1到匯點。pragma comment linker,stack 1024000000,1024000000 include include ...

插頭Uva753 最大流

題意 n個插座和m個插頭,k種轉換器 每種都是無限個,可以把插頭轉換成其他型別的插頭 求最少剩多少個插頭沒插上插座。思路 首先給所有插頭或插座以及轉換器中涉及到的型別編號。然後根據轉換器建立型別之間的轉化關係,接著用floyd演算法算出每個裝置所有適配的型別,並將其容量設為inf,表示轉換器數量充足...