hdu 5305 Friends(dfs)

来源:互联网 发布:天猫精灵 小爱 知乎 编辑:程序博客网 时间:2024/05/17 05:08

Friends

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5305

解题思路:

由于总点数很少,我们考虑暴力。但是总的边数有(8*7)/2=28,所以直接枚举每条边的状态无疑会TLE。又注意到如果存在一个

点的度数为奇数,那么最后答案肯定时0,每个点度数都为偶数时,总边数最多为(8*6)/2=24.还是一个蛮大的数字。最后一个优

化是,每次搜索一个点时,枚举到最后一条边的状态是不用枚举的,这条边是黑还是白是已经确定了的(根据前面选择的边的黑白

状态),也就是说需要搜索的边数减少n-1,那么最多只要搜索17条边。至此就可以无压力出解了。。。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;int n,m;int a[30],b[30],cnt;int sum[10],on[10],off[10];//sum记录每个点的度数,on记录每个点的online,off记录每个点的offlinebool judge(){    for(int i = 1; i <= n; i++){        if(on[i] != off[i])            return false;    }    return true;}void dfs(int cur){    if(cur == m+1){        if(judge()){            cnt++;            return;        }    }    int x = a[cur], y = b[cur];    if(on[x] < sum[x]/2 && on[y] < sum[y]/2){        on[x]++;        on[y]++;        dfs(cur+1);        on[x]--;        on[y]--;    }    if(off[x] < sum[x]/2 && off[y] < sum[y]/2){        off[x]++;        off[y]++;        dfs(cur+1);        off[x]--;        off[y]--;    }}int main(){    int T;    scanf("%d",&T);    while(T--){        memset(on,0,sizeof(on));        memset(off,0,sizeof(off));        memset(sum,0,sizeof(sum));        int flag = 1;        cnt = 0;        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]]++;        }        for(int i = 1; i <= n; i++){            if(sum[i] % 2){                flag = 0;                break;            }        }        if(flag){            dfs(1);            printf("%d\n",cnt);        }        else            printf("0\n");    }    return 0;}


0 0
原创粉丝点击