zoukankan      html  css  js  c++  java
  • hdu3472 混合图判断欧拉通路

    对于欧拉回路,先判断出度入度的差是否为偶数,然后最大流一次。

    此题是判断有无欧拉通路,前提要判断图是否连通,然后欧拉通路的条件:要么出入度差没有奇数,或者只有2个点。

    所以先统计差为奇数的个数,如果不为0或2,不可能。然后如果为2,表示可能使欧拉路,所以此时可以将这两个点相连,类似添加一条无向边。然后就是判断是否为欧拉回路了。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #define maxn 50
    #define INF 9999999
    using namespace std;
    struct node
    {
        int to;
        int v;
        int flag;
        int next;
    }edge[1000*1000];
    char s[1002][25];
    int vis[maxn],pre[maxn],index,in[maxn],out[maxn],n,sum,t,ff;
    int pa[maxn];
    int find(int x)
    {
        if(pa[x]!=x)pa[x]=find(pa[x]);
        return pa[x];
    }
    void add(int x,int y,int z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].flag=index+1;
        edge[index].next=pre[x];
        pre[x]=index++;
        edge[index].to=x;
        edge[index].v=0;
        edge[index].flag=index-1;
        edge[index].next=pre[y];
        pre[y]=index++;
    }
    int dfs(int u,int low)
    {
        int i;
        if(u==t)
            return low;
        for(i=pre[u];i!=-1;i=edge[i].next)
        {
            if(vis[edge[i].to]==vis[u]+1&&edge[i].v)
            {
                int a=dfs(edge[i].to,min(low,edge[i].v));
                if(!a)continue;
                edge[i].v-=a;
                edge[edge[i].flag].v+=a;
                return a;
            }
        }
        return 0;
    }
    int BFS()
    {
        int i;
        queue<int>q;
        memset(vis,-1,sizeof(vis));
        vis[0]=0;
        q.push(0);
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            for(i=pre[t];i!=-1;i=edge[i].next)
            {
                if(vis[edge[i].to]<0&&edge[i].v)
                {
                    vis[edge[i].to]=vis[t]+1;
                    q.push(edge[i].to);
                }
            }
        }
        if(vis[t]>0)
            return 1;
        return 0;
    }
    void Dinic()
    {
        int ans=0;
        while(BFS())
        {
            while(1)
            {
                int a=dfs(0,INF);
                if(!a)break;
                ans+=a;
            }
        }
        if(ans==sum)
           printf("Case %d: Well done!
    ",++ff);
        else
            printf("Case %d: Poor boy!
    ",++ff);
    }
    void slove(int fs)
    {
        int i,st,se;//欧拉路奇数点的开始结束点
        st=se=-1;
        int count=0,flag=0;
        for(i=1;i<='z'-'a'+1;i++)
        {
            if(in[i]||out[i])
            {
                if(find(i)!=find(fs))
                {
                    flag=1;
                    break;
                }
                else if((out[i]-in[i])%2!=0)
                {
                    count++;
                    if(st==-1)st=i;
                    else se=i;
                }
            }
        }
        if(count!=0&&count!=2) flag=1;
    
        if(flag)
            printf("Case %d: Poor boy!
    ",++ff);
        else
        {
            if(count==2)
            {
                add(st,se,1);
                out[st]++;
                in[se]++;
            }
            for(i=1;i<='z'-'a'+1;i++)
            {
                if(out[i]>in[i])
                {
                    add(0,i,(out[i]-in[i])/2);
                    sum+=((out[i]-in[i])/2);
                }
                else if(in[i]>out[i])
                {
                    add(i,t,(in[i]-out[i])/2);
                }
            }
            Dinic();
        }
    }
    int init()
    {
        int i,fs;
        t='z'-'a'+2;
        sum=0;
        index=1;
        for(i=0;i<=30;i++)pa[i]=i;
        memset(pre,-1,sizeof(pre));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            int z;
            scanf("%s %d",s[i],&z);
            int l=strlen(s[i]);
            int x=s[i][0]-'a'+1;
            int y=s[i][l-1]-'a'+1;
            in[y]++,out[x]++,fs=x;
            int fx=find(x),fy=find(y);
            if(fx!=fy)pa[fx]=fy;
            if(z)
            {
                add(x,y,1);
            }
        }
        return fs;
    }
    int main()
    {
        ff=0;
        int t,father;
        scanf("%d",&t);
        while(t--)
        {
            father=init();
            slove(father);
        }
    }
  • 相关阅读:
    DataGrip for Mac破解步骤详解 亲测好用
    git 之路
    linux用户管理
    virtualenvwrappers pipreqs 踩坑
    pycharm 快捷键
    kubernetes(k8s)之K8s部署多种服务yaml文件
    centos下彻底删除mysql的方法
    vi 和vim 的区别
    Django中related_name作用
    Windows CMD命令大全
  • 原文地址:https://www.cnblogs.com/sweat123/p/4869330.html
Copyright © 2011-2022 走看看