zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    zbb20181207 springboot @ConfigurationProperties使用
    zbb20181206 logback,lombok 默认日志logback配置解析
    Spring Boot (8) 全局异常处理
    Spring Boot (7) JdbcTemplate访问数据库
    Spring Boot (6) Spring Data JPA
    Spring Boot (4) 静态页面和Thymeleaf模板
    Spring Boot (3) 热部署devtools
    Spring Boot (2) Restful风格接口
    Spring Boot (1) 构建第一个Spring Boot工程
    idea使用maven搭建ssm框架实现登陆商品增删改查
  • 原文地址:https://www.cnblogs.com/vermouth/p/3839712.html
Copyright © 2011-2022 走看看