POJ 1637 最大流+欧拉回路

来源:互联网 发布:中药的软件 编辑:程序博客网 时间:2024/06/06 05:56
#include<cstring>#include<iostream>#include<iomanip>#include<queue>#include<cmath>#include<stack>#include<map>#include<vector>#include<set>#include<algorithm>using namespace std;typedef long long LL;const int int_max = 0x07777777;const int int_min = 0x80000000;const int maxn = 250;struct Edge{    int from, to, cap, flow;    Edge(int _from, int _to, int _cap, int _flow):from(_from),to(_to),cap(_cap),flow(_flow){}};vector<Edge> es;vector<int> g[maxn];int s,t;int p[maxn],d[maxn],gap[maxn],cur[maxn];void addedge (int from, int to, int cap){    es.push_back(Edge(from, to, cap, 0));    es.push_back(Edge(to, from, 0,0));    int num = es.size();    g[from].push_back(num-2);    g[to].push_back(num-1);}void BFS (){    queue<int> q;    memset(d, -1, sizeof(d));    d[t] = 0;    q.push(t);    while(!q.empty()){        int u = q.front();        q.pop();        for(int i = 0; i < g[u].size(); i++){            Edge& e = es[g[u][i]];            if(g[u][i]&1 && d[e.to]==-1){                d[e.to] = d[u]+1;                q.push(e.to);            }        }    }}int augment (){    int x = t;    int a = int_max;    while(x!=s){        Edge& e = es[p[x]];        a = (a < e.cap-e.flow ? a : e.cap-e.flow);        x = es[p[x]].from;    }    x = t;    while(x!=s){        es[p[x]].flow += a;        es[p[x]^1].flow -= a;        x = es[p[x]].from;    }    return a;}int sap (){    int flow = 0;    BFS();    memset(gap, 0, sizeof(gap));    for(int i = 0; i <= t; i++) if(d[i]!=-1) gap[d[i]]++;    int x = s;    memset(cur, 0, sizeof(cur));    while(d[s] < t+1){        if(x==t){            flow += augment();            x = s;        }        int ok = 0;        for(int i = 0; i < g[x].size(); i++){            Edge& e = es[g[x][i]];            if(e.cap > e.flow && d[x]==d[e.to]+1){                ok = 1;                p[e.to] = g[x][i];                cur[x] = i;                x = e.to;                break;            }        }        if(!ok){            int mm = t;            for(int i = 0; i < g[x].size(); i++){                Edge& e = es[g[x][i]];                if(e.cap > e.flow) mm = (mm > d[e.to] ? d[e.to] : mm);            }            if(--gap[d[x]] == 0) break;            gap[d[x]=mm+1]++;            cur[x] = 0;            if(x!=s) x = es[p[x]].from;        }    }    return flow;}int n,m;int main(int argc, const char * argv[]){    int T;    scanf("%d", &T);    while(T--){        scanf("%d %d", &n, &m);        es.clear();        for(int i = 0; i < maxn; i++) g[i].clear();        s = 0;        t = n+1;        int ru[maxn],chu[maxn],rr[maxn];        memset(ru, 0, sizeof(ru));        memset(chu, 0, sizeof(chu));        memset(rr, 0, sizeof(rr));        for(int i = 0; i < m; i++){            int x,y,z;            scanf("%d %d %d", &x, &y, &z);            if(x==y) continue;            if(z==0){                addedge(x, y, 1);                addedge(y, x, 1);                rr[x]++;                rr[y]++;            }else{                chu[x]++;                ru[y]++;            }        }        int total = 0;        for(int i = 1; i <= n; i++){            if(ru[i]-chu[i] > 0) addedge(s, i, ru[i]-chu[i]);            if(chu[i]-ru[i] > 0) addedge(i, t, chu[i]-ru[i]);            if(ru[i] > chu[i]) total += ru[i]-chu[i];        }        if(total==0){            int flag = 1;            for(int i = 1; i <= n; i++){                if(rr[i]&1){                    flag = 0;                    break;                }            }            if(flag) cout << "possible" << endl;            else cout << "impossible" << endl;            continue;        }        int result = sap();        if(result==total) cout << "possible" << endl;        else cout << "impossible" << endl;    }}

0 0