HDU 6321 Dynamic Graph Matching 狀壓,揹包
阿新 • • 發佈:2018-11-02
題意:n個點的圖,初始沒有邊. m次操作,新增或者刪除邊(u,v).
n<=10,m<=3e4. 每次操作後,詢問k=[1,2...n/2]的匹配方案數?
n<=10. 設dp[i][s] 第i次操作後,點s中的所有bit為1的點,都相互匹配的方案數.
新增一條邊:dp[i][s]= dp[i-1][s]+ dp[i-1][s-{u,v}] (s中用(u,v)匹配 或者不用(u,v)匹配.)
刪除一條邊:dp[i][s]= dp[i-1][s]- dp[i-1][s-{u,v}] (邊(u,v)被刪除 要刪除用(u,v)匹配的方案數).
s中有x個1 就貢獻x/2個匹配.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e4+5,M=1030,mod=1e9+7; int T,n,m,u,v,bit[M]; ll dp[M],f[7]; char op[3]; int main(){ scanf("%d",&T); memset(bit,0,sizeof(bit)); for(int s=0;s<M;s++) for(int j=0;j<10;j++) if((s>>j)&1) bit[s]++; while(T--){ scanf("%d%d",&n,&m); int S=1<<n; for(int i=1;i<=m;i++){ memset(f,0,sizeof(f)); dp[0]=1; scanf("%s%d%d",op,&u,&v); u--,v--; int ss=(1<<u) + (1<<v); if(op[0]=='+'){ for(int s=S-1;s>=0;s--) if((s&ss)==ss) dp[s]=(dp[s]+dp[s^ss])%mod; } else{ for(int s=S-1;s>=0;s--) if((s&ss)==ss) dp[s]=(dp[s]-dp[s^ss]+mod)%mod; } ll res=0; for(int s=0;s<S;s++){ int cnt=bit[s]; if(cnt%2) continue; cnt/=2; f[cnt]=(f[cnt]+dp[s])%mod; } printf("%d",f[1]); for(int k=2;k<=n/2;k++) printf(" %d",f[k]); printf("\n"); } } return 0; }