hdu5305

题目名称:Friends

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5305


题意:给定n个人,m对朋友关系,朋友关系可以选择online聊天,也可以选择offline,对于每个人,他选择的online和offline的朋友相同(比如拥有x个online,就得拥有x个offline),问全部人满足有多少种情况?只要一个选择不同,视为不同情况。


思路(hdu的题解):由于总点数很少,我们考虑暴力,但总的边数有8*7/2=28,所以会TLE,一个点的度数为奇数时,答案肯定为0,每个点为偶数时,总边数最多为8*6/2=24,还是一个较大的数字。最后一个优化是搜索一个点到最后一条边时不用枚举,因为已经确定了。也就是说搜索边数少n-1,所以只要搜索17条边,暴力就可以了,,

搜索他给的那些边,然后可以为online或者offline,最后判断每个点的online朋友和offline朋友是否相等就行了,相等就总数加一


代码如下:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int d1[10],d2[10],sum[10];  //d1表示online,d2表示offline
int n,m;
int ans=0,a[30],b[30];
int judge()     //判断online和offline相等
{
    for(int i=1;i<=n;i++)
    {
        if(d1[i]!=d2[i])
            return 0;
    }
    return 1;
}
void dfs(int num)     //num表示第几组关系
{
    if(num==m+1)
    {
        if(judge())
            ans++;
        return ;
    }
    int x=a[num],y=b[num];
    if((d1[x]<sum[x]/2)&&(d1[y]<sum[y]/2))   //假设该边为online
    {
        d1[x]++;
        d1[y]++;
        dfs(num+1);
        d1[x]--;        //记得修改的边要及时修改回来
        d1[y]--;
    }
    if((d2[x]<sum[x]/2)&&(d2[y]<sum[y]/2))
    {
        d2[x]++;
        d2[y]++;
        dfs(num+1);
        d2[x]--;
        d2[y]--;
    }
}
int main()
{
    int t;
    while(scanf("%d",&t)!=EOF)
    {
        while(t--)
        {
            memset(d1,0,sizeof(d1));
            memset(d2,0,sizeof(d2));
            memset(sum,0,sizeof(sum));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&a[i],&b[i]);
                sum[a[i]]++;
                sum[b[i]]++;
            }
            ans=0;
            int ok=1;
            for(int i=1;i<=n;i++)    //为奇数时说明不成立
            {
                if(sum[i]&1)
                {
                    ok=0;
                    break;
                }
            }
            if(ok)
            {
                dfs(1);
                printf("%d\n",ans);
            }
            else
                printf("0\n");
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章