http://www.cnblogs.com/looker_acm/archive/2010/08/15/1799919.htmlhtml
/* ** 混合圖歐拉回路 ** 只記錄各定點的出度與入度之差,有向邊無用丟棄,將無向邊定向,在網絡中創建流量爲1的邊 ** 另新建s和t。對於入 > 出的點u,鏈接邊(u, t)、容量爲x,對於出 > 入的點v,鏈接邊(s, v), ** 容量爲x(注意對不一樣的點x不一樣)。以後,察看是否有滿流的分配,若是是滿流則存在,不然不存在 */ #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; const int maxn = 300; const int maxm = maxn*10; struct node{ int v,next,flow; }edge[maxm]; int head[maxn],dis[maxn],deg[maxn]; int id,source,sink; void add_edge(int u,int v,int flow){ edge[id].v = v;edge[id].flow = flow;edge[id].next = head[u];head[u] = id++; edge[id].v = u;edge[id].flow = 0 ;edge[id].next = head[v];head[v] = id++; } bool spfa(){ memset(dis,-1,sizeof(dis)); dis[source] = 0; queue<int>que; que.push(source); while(!que.empty()){ int u = que.front(); que.pop(); for(int id = head[u]; id != -1; id = edge[id].next){ int v = edge[id].v; if( edge[id].flow > 0 && dis[v] == -1){ dis[v] = dis[u] + 1; que.push(v); } } } return dis[sink] != -1; } int dinic(int u,int flow){ if( u == sink)return flow; int tmp = flow; for(int id = head[u]; id != -1; id = edge[id].next){ int v = edge[id].v; if( edge[id].flow > 0 && dis[v] == dis[u] + 1){ int tt = dinic(v,min(edge[id].flow ,tmp)); tmp -= tt; edge[id].flow -= tt; edge[id^1].flow += tt; if( tmp == 0)return flow; } } return flow - tmp; } int get_max(){ int max_flow = 0; while( spfa()) max_flow += dinic(source,100000); return max_flow; } int main(){ int t,n,m; int u,v,d; scanf("%d",&t); while( t-- ){ scanf("%d%d",&n,&m); for(int i = 0; i <= n+1; i++) deg[i] = 0,head[i] = -1; id = source = 0;sink = n+1; while( m-- ){ scanf("%d%d%d",&u,&v,&d); if( u == v)continue; deg[u]++,deg[v]--; if( d == 0)add_edge(u,v,1); } bool flg = false; int ans = 0; for(int i = 1;i <= n; i++){ if( deg[i]%2 ){flg = true;break;} deg[i] /= 2; if( deg[i] > 0){ ans += deg[i]; add_edge(source,i,deg[i]); } else add_edge(i,sink,-deg[i]); } if( flg || ans != get_max())puts("impossible"); else puts("possible"); } return 0; }