poj 1637 混合图欧拉回路,最大流

来源:互联网 发布:ubuntu安装openstack 编辑:程序博客网 时间:2024/05/21 08:47

传送门

题意:给你一个混合图,问能否从一个点出发经过所有边回到这个点。

思路:一头雾水,借鉴前人博客,现在方法会了,马上吃饭走路时再深入想想为什么可以这样吧。

前人博客

#include<iostream>#include<cstdio>#include<cstring>#define maxn 1<<29using namespace std;int fst[300],next[3000],node[3000],c[3000],en;int f[3000],in[300],pre[300],lu[300];int m,n,tt,sum,s,t,q[100000];bool flag;bool vis[300];void init(){    en=0;    flag=0;    memset(fst,-1,sizeof(fst));    memset(f,0,sizeof(f));    memset(in,0,sizeof(in));}void add(int u,int v,int a){    next[en]=fst[u];    fst[u]=en;    node[en]=v;    c[en]=a;    en++;    next[en]=fst[v];    fst[v]=en;    node[en]=u;    c[en]=0;    en++;}bool bfs(){    memset(vis,0,sizeof(vis));    int front=0,end=0;    q[end++]=s;    vis[s]=1;    while(end>front)    {        int u=q[front++];        for(int i=fst[u];i!=-1;i=next[i])        {            int v=node[i];            if(!vis[v]&&c[i]-f[i]>0)            {                vis[v]=1;                pre[v]=u;                lu[v]=i;                if(v==t)return true;                q[end++]=v;            }        }    }    return false;}int ek(){    int flow=0;    while(bfs())    {        int mm=maxn;        for(int i=t;i!=s;i=pre[i])        {            int v=lu[i];            if(c[v]-f[v]<mm)mm=c[v]-f[v];        }        for(int i=t;i!=s;i=pre[i])        {            int v=lu[i];            f[v]+=mm;            f[v^1]-=mm;        }        flow+=mm;    }    return flow;}int main(){    int u,v,a;    scanf("%d",&tt);    while(tt--)    {        init();        scanf("%d%d",&n,&m);        s=0;        t=n+1;        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u,&v,&a);            if(!a)            {                add(u,v,1);            }            in[v]++;            in[u]--;        }        sum=0;        for(int i=1;i<=n;i++)        {            if(in[i]%2)            {                flag=1;                break;            }            int co=in[i]/2;            if(co>0)            {                add(i,t,co);                sum+=co;            }            else add(0,i,-co);        }        if(flag)        {            cout<<"impossible"<<endl;            continue;        }        if(sum==ek())cout<<"possible"<<endl;        else cout<<"impossible"<<endl;    }    return 0;}


原创粉丝点击