HDU 5305 Friends

来源:互联网 发布:ascara 知乎 编辑:程序博客网 时间:2024/05/03 01:56

题目地址:点击打开链接

思路:先贴一下官方题解,


最多搜17条边没太搞懂,感觉是对点深搜才能用到,对边深搜用不到

题意是给了n个人,m个关系,这种关系可以是线上关系,也可以是线下关系(题目只说了是朋友关系,害得我半天才搞明白),然后使每个人的线下和线上关系的人数相同,问有多少种方法,扯点题外话,DFS一般是求可能性,即从这个点走到那个点是否可能,而后求方法的可能性,这样就变成了回溯,搜索的方法我目前知道的只有2种,对点深搜,对边深搜

给一个无向图 , 每条边可以是online边也可以是offline边,问有多少种方法使得每个节点的online边和offline边一样多

AC代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;struct point{    int x,y;}edge[30];int sum[10],on[10],off[10],n,m,ans;void dfs(int cur){    int i,point1,point2;    if(cur == m)    {        for(i=1; i<=n; i++)        {            if(on[i] != off[i])                break;        }        if(i<=n)            return;        else            ans++;        return;    }    point1 = edge[cur].x;    point2 = edge[cur].y;    if(on[point1] < sum[point1]/2 && on[point2] < sum[point2]/2)//线上朋友没有达到总和的一半,可以继续加    {        on[point1]++;        on[point2]++;        dfs(cur+1);        on[point1]--;        on[point2]--;    }    if(off[point1] < sum[point1]/2 && off[point2] < sum[point2]/2)    {        off[point1]++;        off[point2]++;        dfs(cur+1);        off[point1]--;        off[point2]--;    }}int main(){    int t,i;    scanf("%d",&t);    while(t--)    {        memset(sum,0,sizeof(sum));        memset(on,0,sizeof(on));        memset(off,0,sizeof(off));        ans = 0;        scanf("%d%d",&n,&m);        for(i=0; i<m; i++)        {            scanf("%d%d",&edge[i].x,&edge[i].y);//一条边的2个点            sum[edge[i].x]++;            sum[edge[i].y]++;        }        for(i=1; i<=n; i++)//一个点的边数为奇数直接退出        {            if(sum[i] % 2 != 0)                break;        }        if(i<=n)            printf("0\n");        else        {            dfs(0);            printf("%d\n",ans);        }    }    return 0;}

大神地址:点击打开链接

0 0