天天看點

混合圖歐拉回路POJ1637Sightseeing tour

http://www.cnblogs.com/looker_acm/archive/2010/08/15/1799919.html

/*
**  混合圖歐拉回路
**  隻記錄各定點的出度與入度之差,有向邊無用丢棄,将無向邊定向,在網絡中建立流量為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;
}
           

轉載于:https://www.cnblogs.com/LUO257316/p/3288564.html