2015多校训练第二场 hdu5305

来源:互联网 发布:内帐软件 编辑:程序博客网 时间:2024/06/05 02:57
        把这题想复杂了,一直在考虑怎么快速的判断将选的边和已选的边无冲突,后来经人提醒发现这根本没必要,反正数据也不大开两个数组爆搜就OK了,搜索之前要先排除两种没必要搜的情况,这很容易想到,爆搜的时候注意几个小细节就可以了(代码代码注释中已标好)

#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<utility>using namespace std;typedef pair<int,int> P;vector<int> gt[30];int g[36][36];int c0[36],c1[36];int count;int n,m;void dfs(int x,int y){    if(x>n)    {        count++;//        printf("%d\n",count);        return;    }    else if(y>n)    {        if(c0[x]!=c1[x]) return;        dfs(x+1,x+2);   //  注意这里不是从1开始  原因很简单 因为前面的都已经标记过了    }    else    if(g[x][y])    {        c0[x]++;        c0[y]++;    //  注意这里是y  把一条边划分之后,两个点都被划分了        dfs(x,y+1);        c0[x]--;        c0[y]--;        c1[x]++;        c1[y]++;        dfs(x,y+1);        c1[x]--;        c1[y]--;    }    else if(g[x][y]==0) dfs(x,y+1);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        count=0;        scanf("%d%d",&n,&m);        memset(g,0,sizeof(g));        memset(c1,0,sizeof(c1));        memset(c0,0,sizeof(c0));        for(int k=1;k<=n;k++)           gt[k].clear();        for(int i=0;i<m;i++)        {            int a,b;            scanf("%d%d",&a,&b);            gt[a].push_back(b);            gt[b].push_back(a);            g[a][b]=g[b][a]=1;        }        int f=0;        for(int j=1;j<=n;j++)        {            if(gt[j].size()%2) f=1;        }        if(f||m%2)        {            printf("0\n");            continue;        }        dfs(1,2);   //  0 代表 网络  1代表现实        printf("%d\n",count);    }}

 

,无脑不许想太多、、、、

 

0 0
原创粉丝点击