• hdu 3472 HS BDC 混合欧拉 网络流


    题意就是问能否将给定的几个单词全部连接起来,两个单词能连接是当前一个单词的最后一个字母等于后一个单词的首字母。还有一些单词反向也没有关系。

    建图,每输入一个单词,只看他的首尾字母,连接一条首字母到尾字母的有向边,如果他可以反向,那么再反向建立一条边,即该边是无向边。然后就是一个混合欧拉了。

    还有一个注意的地方,就是可能是欧拉道路,这时只要在添加一条边连接两个奇度节点就好。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    #define inf 100000
    const int maxn=100;
    int n,m;
    int p[50],in[50],out[50];
    int level[maxn],que[maxn];
    int head[maxn],lon;
    int min(int a,int b)
    {
        if(a<b) return a;
        else return b;
    }
    struct edge
    {
        int next,to,c;
    }e[200000];
    void edgeini()
    {
        memset(head,-1,sizeof(head));
        lon=-1;
    }
    void edgemake(int from,int to,int c)
    {
        e[++lon].c=c;
        e[lon].to=to;
        e[lon].next=head[from];
        head[from]=lon;
    }
    void make(int from,int to,int c)
    {
        edgemake(from,to,c);
        edgemake(to,from,0);
    }
    
    bool makelevel(int s,int t)
    {
        memset(level,0,sizeof(level));
        int front=1,end=0;
        que[++end]=s;
        level[s]=1;
        while(front<=end)
        {
            int u=que[front++];
            if(u==t) return true;
            for(int k=head[u];k!=-1;k=e[k].next)
            {
                int v=e[k].to;
                if(!level[v]&&e[k].c)
                {
                    que[++end]=v;
                    level[v]=level[u]+1;
                }
            }
        }
        return false;
    }
    
    int dfs(int now,int t,int maxf)
    {
        if(now==t||maxf==0) return maxf;
        int ret=0;
        for(int k=head[now];k!=-1;k=e[k].next)
        {
            int u=e[k].to;
            if(level[u]==level[now]+1&&e[k].c)
            {
                int f=dfs(u,t,min(e[k].c,maxf-ret));
                e[k].c-=f;
                e[k^1].c+=f;
                ret+=f;
                if(ret==maxf) return ret;
            }
        }
        if(ret==0) level[now]=0;
        return ret;
    }
    
    int maxflow(int s,int t)
    {
        int ret=0;
        while(makelevel(s,t))
        {
            ret+=dfs(s,t,inf);
        }
        return ret;
    }
    int find (int x)
    {
        if(x==p[x]) return x;
        else return p[x]=find(p[x]);
    }
    void link(int a,int b)
    {
        int fa=find(a);
        int fb=find(b);
        if(fa!=fb)
            p[fa]=fb;
    }
    int main()
    {
        char str[30];
        int cas;
        int s,t;
        int s1,s2;
        int sum=0;
        scanf("%d",&cas);
        while(cas--)
        {
            sum++;
            int i,j;
            int now;
            int len,flag,u,v,mk;
            for(i=1;i<=30;i++) p[i]=i;
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            scanf("%d",&m);
            s=0;t=30;
            edgeini();
            for(i=1;i<=m;i++)
            {
                scanf("%s",str);
                len=strlen(str);
                scanf("%d",&mk);
                u=str[0]-'a'+1;
                v=str[len-1]-'a'+1;
                now=v;
                out[u]++;
                in[v]++;
                link(u,v);
                if(mk==1)
                    make(u,v,1);
            }
            int cnt=0;
            flag=1;
            s1=s2=-1;
            for(i=1;i<=30;i++)
            {
                if(in[i]||out[i])
                {
                    if(find(i)!=find(now))
                    {
                        flag=0;
                        break;
                    }
                    if((out[i]+in[i])%2==1)
                    {
                        cnt++;
                        if(s1==-1)s1=i;
                        else s2=i;
                    }
                }
            }
            if(cnt!=0&&cnt!=2) flag=0;
            if(flag==0)
            {
                printf("Case %d: Poor boy!
    ",sum);
                continue;
            }
            if(cnt==2)
            {
                out[s1]++;
                in[s2]++;
                make(s1,s2,1);
            }
            for(i=1;i<=30;i++)
            {
                if(out[i]-in[i]>0)
                     make(s,i,(out[i]-in[i])/2);
                else if(in[i]-out[i]>0)
                     make(i,t,(in[i]-out[i])/2);
            }
            int flow=maxflow(s,t);
            for(i=head[s];i!=-1;i=e[i].next)
            {
                if(e[i].c>0)
                    flag=0;
            }
            if(flag)printf("Case %d: Well done!
    ",sum);
            else printf("Case %d: Poor boy!
    ",sum);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    部门创建注意问题
    我的技术博客开通啦~
    听侯钟雷老师的讲座,确认了几个问题。
    Dynamics CRM 批量添加用户时,报错:Server was unable to process request.
    汉字的Unicode范围(转)
    转载:Apache1.1 post请求无body的bug
    转载:Android有效解决加载大图片时内存溢出的问题
    2.2之前的webkit crash问题
    转载:Expect:100Continue & HTTP 417 Expectation
    城市旅游问题
  • 原文地址:https://www.cnblogs.com/vermouth/p/3839712.html
Copyright © 2020-2023  润新知