回 帖 发 新 帖 刷新版面

主题:[讨论]这道题怎么做啊~~~

Description 

ACMer在ZQU已经有好几年的历史了,最近,他们想成立一个协会,叫ZQU_ICPC协会。我们都知道,在ZQU成立一个协会是需要很多手续的,而且还有一个人数上的条件,即必须满足一定的人数才可以得到学校的批准。 
所以,现有的ACMer开始到处宣传,希望能够找到尽量多的人进入协会。 
现在给出同学们的关系以及最开始的ACMer的号码。 
请问他们的人数足够满足条件吗? 


Input 

输入有多个测试用例。 
每个测试用例的第一行是三个数字n,m和num,n表示一共有多少个人,m表示有多少同学之间是有关系的,num表示成立协会的最少人数。( 1 < n <100 ,m<200 , num <= n ) 
接下来有m行,每行两个数字 a b,表示a和b有关系,只要其中一个加入ZQU_ICPC协会,那么另外一个也会加入到ACMer的行列。 
接下来一行是一个数字k,表示最开始有k个ACMer,接下来一行有k个数字(0 <= ki < n)表示最初的ACMer们的编号。 


Output 

对于每个测试用例,如果满足人数上的条件,输出"YES",否则输出"SORRY"

Sample Input 


10 5 5
1 2
0 2
6 7
4 2
3 1
1     // 最开始有多少个人  接下来是每个人的编号



Sample Output 


YES


//-----------------------
这是我的代码 但是超时了  有没有更好的方法?
[code=c]
#include <stdio.h>  
#define size 200  

int parents[size];   
int deep[size];   
int s[100];

void INIT(int x)   
{   
    parents[x] = x;   
    deep[x] = 0;   
}   

int Find(int x)   
{   
    int par,tem;   
    par = x;   
    while(parents[par]!=par)   
        par = parents[par];   
    while (x!=par)   
    {   
        tem = parents[x];   
        parents[x] = par;   
        x = tem;   
    }   
    return par;   
}   

void Union(int a,int b)   
{   
    int t1 = Find(a);   
    int t2 = Find(b);   
    if(deep[t1]<deep[t2])   
        parents[t1] = t2;   
    else  
        parents[t2] = t1;   
    if(deep[t1] == deep[t2])   
        deep[t1]++;   
}   

int Search(int t,int j)
{
    int i;
    for(i=0;i<j;i++)
    {
        if(t == s[i])
        {
            return 1;
        }
    }
    return 0;
}

int main()   
{   
    int i,k,j,ii,jj;   
    int peo,known,needs,n,t,sum;   
    int a,b;         
    while(scanf("%d%d%d",&peo,&known,&needs))
    {  
        for(i=0;i<peo;i++)   
            INIT(i);   
        while(known--)   
        {   
            scanf("%d%d",&a,&b);   
            if(Find(a)!=Find(b))   
                Union(a,b);   
        } 
        sum=0;
        j=0;
        scanf("%d",&n);
        for(k=0;k<n;k++)
        {
            scanf("%d",&t);
            t=Find(t);
            if(Search(t,j))
            {
                continue;
            }
            s[j]=t;j++;
            for(i=0;i<peo;i++)
            {
                if(Find(i) == t)
                {
                    sum++;
                }
            }
        }
        if(sum >= needs)
        {
            printf("YES\n");
        }
        else
        {
            printf("SORRY\n");
        }
    }   
    return 0;   
}[/code]

回复列表 (共4个回复)

沙发

Input 我看了两遍都没看懂 可能是我语文学的太差了

板凳


好象没有什么问题,可以运行

3 楼

求lz把input那里的代码注释一下,看到n m num的变量风格都可读性很高,但是又冒出一堆ii jj这样平时不常见的标志变量,就彻底晕了

4 楼

[code=c]
int Find(int x)   
{   
    int par,tem;   
    par = x;   
    while(parents[par]!=par)   
        par = parents[par];   
    while (x!=par)   
    {   
        tem = parents[x];   
        parents[x] = par;   
        x = tem;   
    }   
    return par;   
}   
[/code]
调用INIT()之后,parents[]的下标与其值对应,再判断是否相等还有什么意义?

录入第一行的三个数据,在最后加以判断,又为什么要把判断放在while之外?

就看过一点数据结构,这太像图了。

我来回复

您尚未登录,请登录后再回复。点此登录或注册