Sightseeing tour(混合图的欧拉回路是否存在)

题目

rt

首先,我们将无向路强制转化为有向路,并将其建图(流量为1)

相当于你先搞成有向图,先判一遍(abs(in[i]]-out[i]))%2

然后,我们分别找出in[i]>out[i]&&in[i]<out[i]的点

将其分别与t,s,建边(流量为差值减一)

以为将其中某些路径反向,以得到满流;

当然如果结果未满流,则也不可能

#include<iostream>
#include<queue>
#define re return
#define R register 
#define ll long long 
#define inc(i,l,r) for(register int i=l;i<=r;++i)
const int maxn=100005,maxm=2000005;
using namespace std;
char buf[1<<21],*p1,*p2;
inline int gc(){re p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} 
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

int n,m,k=1,cnt=0,s,t;
int hd[maxn],in[maxn],out[maxn],cur[maxn];
int deep[maxn];
struct node{
    int to,nt,flow;
}e[maxm];

inline void add(int x,int y,int f)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].flow=f;
    e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].flow=0;
}

inline bool bfs()
{
    queue<int>q;
    inc(i,s,t)deep[i]=0;
    deep[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=hd[u];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(!deep[v]&&e[i].flow)
            {
                deep[v]=deep[u]+1;
                if(v==t)re 1;
                q.push(v);
            } 
        }
    }
    re 0;
}

inline int dfs(int x,int flow)
{
    if(x==t)re flow;
    int delta=flow;
    for(int& i=cur[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(deep[v]==deep[x]+1&&e[i].flow)
        {
            int d=dfs(v,min(delta,e[i].flow));
            e[i].flow-=d;
            e[i^1].flow+=d;
            delta-=d;
            if(!delta)re flow;
            
        }
    }
    re flow-delta;
    
}

int main()
{
    int T,x,y,z;
    rd(T);
    while(T--)
    {
        int falg=0,ans=0;
        rd(n),rd(m);
        
        k=1;s=0;t=n+1;
        inc(i,s,t)hd[i]=in[i]=out[i]=0;
        inc(i,1,m)
        {
            rd(x),rd(y),rd(z);
            if(!z)add(x,y,1);
            ++out[x];++in[y];
        }
        
        inc(i,1,n)
        {
            int x=in[i]-out[i];
            if(x%2)
            {
                falg=1;
                break;
            }
            else if(x>0)
            {
                add(i,t,x>>1);
                ans+=(x>>1);
            }
            else add(s,i,(-x)>>1);
        }
        
        if(falg)printf("impossible\n");
        else 
        {
            int ret=0;
            while(bfs())
            {
                inc(i,s,t)cur[i]=hd[i];
                ret+=dfs(s,ans);
            }
            if(ret==ans)printf("possible\n");
            else printf("impossible\n");
        }
        
    } 

    re 0;
} 

 

posted @ 2019-08-15 17:48  凉如水  阅读(164)  评论(0编辑  收藏  举报