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; }