zoukankan      html  css  js  c++  java
  • hdu 2768

    求最大留下的观众,观众之间存在不能同时满足的关系,就是矛盾关系,

    矛盾关系建边,建边是双向的所以最大匹配要/2


    还有一种建图的方法:把观众分成两个集合,一个是投留下猫的,一个是投留下狗的

    每个集合间没有矛盾关系,就是二分图了,求出最大匹配,


    两种方法都是要求最大独立集




    #include<stdio.h>
    #include<string.h>
    #define N 510
    int map[N][N],n,m,k,match[N],vis[N];
    struct op
    {
        int love,hate;
    }p[N];
    int find(int x)
    {
        for(int i=1;i<=n;i++)
        {
            if(vis[i]==0&&map[x][i]==1)
            {
                vis[i]=1;
                if(match[i]==-1||find(match[i])==1)
                {
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
        int i,j,sum,t,k;
        int a[2];
        char str[3];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&m,&k,&n);
            for(i=1;i<=n;i++)
            {
                for(j=0;j<2;j++)
                {
                    scanf("%s",str);
                    a[j]=0;
                    if(str[0]=='D')
                    {
                        for(k=1;str[k];k++)
                            a[j]=a[j]*10+str[k]-'0';
                        a[j]+=m;
                    }
                    else if(str[0]=='C')
                        for(k=1;str[k];k++)
                            a[j]=a[j]*10+str[k]-'0';
                }
                p[i].love=a[0];
                p[i].hate=a[1];
            }
            memset(map,0,sizeof(map));
            memset(match,-1,sizeof(match));
            sum=0;
            for(i=1;i<=n;i++)
            {
                for(j=1;j<i;j++)
                    if(p[i].love==p[j].hate||p[i].hate==p[j].love)
                        map[i][j]=map[j][i]=1;
            }
            for(i=1;i<=n;i++)
            {
                memset(vis,0,sizeof(vis));
                sum+=find(i);
            }
            //printf("%d
    ",sum);
            printf("%d
    ",n-sum/2);
        }
        return 0;
    }
    



    #include<stdio.h>
    #include<string.h>
    #define N 510
    int map[N][N],n,m,k,match[N],vis[N],num1,num0;
    struct op
    {
        int cat,dog;
    }p[2][N];
    int find(int x)
    {
        for(int i=1;i<num1;i++)
        {
            if(vis[i]==0&&map[x][i]==1)
            {
                vis[i]=1;
                if(match[i]==-1||find(match[i])==1)
                {
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
        int i,j,sum,t,k;
        char str[10];
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&m,&k,&n);
            num1=num0=1;
            for(j=1;j<=n;j++)
            {
                 scanf("%s",str);
                 if(str[0]=='D')
                 {
                     p[1][num1].dog=0;
                     for(i=1;str[i];i++)
                         p[1][num1].dog=p[1][num1].dog*10+str[i]-'0';
                     scanf("%s",str);
                     p[1][num1].cat=0;
                     for(i=1;str[i];i++)
                         p[1][num1].cat=p[1][num1].cat*10+str[i]-'0';
                     num1++;//选择留下狗的观众人数
                 }
                 else
                 {
                     p[0][num0].cat=0;
                     for(i=1;str[i];i++)
                         p[0][num0].cat=p[0][num0].cat*10+str[i]-'0';
                     scanf("%s",str);
                     p[0][num0].dog=0;
                     for(i=1;str[i];i++)
                         p[0][num0].dog=p[0][num0].dog*10+str[i]-'0';                 
                     num0++;//选择留下猫的观众人数
                 }
            }
            memset(map,0,sizeof(map));
            memset(match,-1,sizeof(match));
            sum=0;
            for(i=1;i<num0;i++)
            {
                for(j=1;j<num1;j++)
                    if(p[0][i].cat==p[1][j].cat||p[0][i].dog==p[1][j].dog)
                        map[i][j]=1;
            }
            for(i=1;i<num0;i++)
            {
                memset(vis,0,sizeof(vis));
                sum+=find(i);
            }
            //printf("%d
    ",sum);
            printf("%d
    ",n-sum);
        }
        return 0;
    }
    


  • 相关阅读:
    [BZOJ 4034][HAOI2015]树上操作(欧拉序列+线段树)
    [BZOJ 4318]OSU!(期望dp)
    [Codeforces Round #146 (Div. 1) B]Let's Play Osu!(期望Dp)
    [Codeforces Round #261 (Div. 2) E]Pashmak and Graph(Dp)
    [Codeforces Round #301 (Div. 2) D]Bad Luck Island(概率Dp)
    [Codeforces Round #284 (Div. 1) B]Name That Tune(概率Dp)
    [UVALive 7143]Room Assignment(Dp)
    [BZOJ 1076][SCOI2008]奖励关(期望+状压Dp)
    【DBMS HKUST slides8】范式及分解算法 知识点总结
    【DBMS HKUST slides1~6】数据库管理系统 知识点总结
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3212593.html
Copyright © 2011-2022 走看看