HDU2470(Get-Together at Stockholm)

/*****************************************************
题意:
Peter邀请朋友参加他的聚会;
但是被邀请的人必须满足:
在聚会中至少有A个认识的人和B个不认识的人;
求最多有多少人会被他邀请;
算法:
根据题目给的数据量,目测这是一道水题;
即通过循环查找找到不合法的结点,删除他对应的关系;
然后继续查找,直到每一个结点都是合法的;
*****************************************************/

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>

using namespace std;

const int N=111;

struct relation
{
    int know,unknow;
} a[N];

int map[N][N];
bool visit[N];
int n,m;
int A,B;

int solve()
{
    int res=n;
    while(1)
    {
        int flag=1;
        for(int i = 0 ; i < n ; i++)
        {
            if(!visit[i]&&(a[i].know<A||a[i].unknow<B))
            {
                visit[i]=1;
                res--;
                flag=0;
                for(int j=0; j<n; j++)
                {
                    if(!visit[j])
                    {
                        if(map[i][j])
                        {
                            a[j].know--;
                        }
                        else
                            a[j].unknow--;
                    }

                }
            }
        }
        if(flag)
            break;//所有的结点全部满足条件
    }
    return res;
}

int main()
{
   //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);
    int tcase = 1;
    while(~scanf("%d%d%d%d",&n,&m,&A,&B))
    {
        if(!n&&!m&&!A&&!B)
            break;
        memset(a,0,sizeof(a));
        memset(map,0,sizeof(map));
        memset(visit,0,sizeof(visit));

        for(int i=0; i<m; i++)
        {
            int u , v;
            scanf("%d%d",&u,&v);
            map[u][v]=map[v][u]=1;
            a[u].know++;
            a[v].know++;
        }

        for(int i=0; i<n; i++)
        {
            a[i].unknow=n-a[i].know-1;//不认的人数=n-认识的和他自己
        }

        printf("Case #%d: %d\n" , tcase++ , solve());
    }
    return 0;
}


你可能感兴趣的:(HDU2470(Get-Together at Stockholm))