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\n",sum);

        printf("%d\n",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\n",sum);

        printf("%d\n",n-sum);

    }

    return 0;

}


 

 

你可能感兴趣的:(HDU)