HDU6321 Problem C. Dynamic Graph Matching
对于每个 检查其是否可以转移到
(对应二进制位上相加)
表示
对应二进制1位的个数
统计
个点的匹配数
,表示集合中有
条边的种类数
#include <bits/stdc++.h>
using namespace std;
const int MAX=1<<10;
const long long MOD=1e9+7;
long long dp[MAX];//记录不同状态的所有匹配数,未全部计入答案数
long long ans[11];
int id[MAX];
void init()//预处理i中1的个数
{
for(int i=1;i<MAX;i++)
id[i]=__builtin_popcount(i);//统计1位
}
int main()
{
int t,n,m,x,y;
char s[2];
init();
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
dp[0]=1;
scanf("%d%d",&n,&m);
while(m--)
{
memset(ans,0,sizeof(ans));
scanf("%s%d%d",s,&x,&y);
int a=1<<(x-1)|1<<(y-1);//表示边
for(int i=0;i<MAX;i++)//所有状态
{
if(!(i&a))//状态中不包含该边
{
if(s[0]=='+') dp[i|a]=(dp[i|a]+dp[i])%MOD;//统计所有能通过该边到最终状态的方法数
else dp[i|a]=(dp[i|a]-dp[i]+MOD)%MOD;//减去通过该边到达最终状态的方法数
}
}
for(int i=3;i<MAX;i++)
ans[id[i]]=(ans[id[i]]+dp[i])%MOD;
for(int i=2;i<=n;i+=2)
printf("%I64d%c",ans[i],i>n-2?'\n':' ');
}
}
return 0;
}