2015多校训练第二场 hdu5305

        把这题想复杂了,一直在考虑怎么快速的判断将选的边和已选的边无冲突,后来经人提醒发现这根本没必要,反正数据也不大开两个数组爆搜就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);

    }

}

 

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

 

你可能感兴趣的:(HDU)