F - Friends-HDU 5305

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


此题我们是先推出 边数m 如果为奇数必然不符合条件。只能为偶数。筛选掉了一半

其次 因为最多8个点,所有最多能构成的图,只有24条边。。

也就是当m>25 ans=0(怎么也无法构成符合条件的图)

然后对1-20 条边的情况下。暴力跑: 每条边用0或1表示这是online边还是offline边。复杂度2^n.  对于因为奇数不可以,只剩下22 24,我们已经推出了24条边是可以的。并且只有一种连法(需要判断一下是否为此连法)。。暴力跑出了答案是2648、只要边数=24且是那一种连法就输出2648,对于22我们也推出22条边是无法构成合法图的,其余情况暴力跑就可以了。。。数据不大。所以也水过了

比较正确的算法应该是 按边来用dfs跑。。加上剪枝也能过


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include<stdlib.h>
#include <queue>
#include <set>
#include <vector>
#define MAX 100
#define inf 0x3f3f3f3f
using namespace std;
#define tree_size MAX*3
struct edge
{
    int a,b,stu;
}A[MAX];
int num[10];
int d[10];
int u[10];
int main()
{
   int t;
   scanf("%d",&t);
   while(t--)
   {
       int n,m;
       scanf("%d%d",&n,&m);
     //  if(m==0)
      //  printf("%d\n",1)
      memset(num,0,sizeof(num));
       for(int i=0;i<m;i++)
       {
           scanf("%d%d",&A[i].a,&A[i].b);
           num[A[i].a]++;
           num[A[i].b]++;
       }
       if(m%2||m>24||m==22)
       {
           printf("0\n");
           continue;
       }
       int flag=0;
       for(int i=1;i<=n;i++)
       {
           if(num[i]%2)
            {
                flag=1;
                break;
            }
       }
       if(flag)
       {
           printf("0\n");
            continue;
       }


       if(m==24)
       {
           flag=0;
           for(int i=1;i<=8;i++)
           {
               if(num[i]!=6)
               {
                   flag=1;
                   break;
               }
           }
           if(!flag)
           {
               printf("2648\n");
               continue;
           }
           else
           {
               printf("0\n");
                continue;
           }
        }


       int s=pow(2.0,m)-1;
       int ans=0;
       for(int i=0;i<=s;i++)
       {
           memset(u,0,sizeof(u));
           memset(d,0,sizeof(d));
           int temp=i;
           for(int j=0;j<m;j++)
            {
                if(temp%2==0)
                    A[j].stu=0;
                else
                    A[j].stu=1;
                temp/=2;
            }
            for(int k=0;k<m;k++)
            {
                if(A[k].stu==0)
                {
                    d[A[k].a]++;
                    d[A[k].b]++;
                }
                else
                {
                        u[A[k].a]++;
                    u[A[k].b]++;
                }
            }
            ans++;
            for(int j=1;j<=n;j++)
            {
                if(d[j]!=u[j])
                {
                    ans--;
                    break;
                }
            }
       }
       printf("%d\n",ans);


   }



    return 0;

}


你可能感兴趣的:(F - Friends-HDU 5305)