hdu多校第3场C. Dynamic Graph Matching

Problem C. Dynamic Graph Matching

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1215    Accepted Submission(s): 505


Problem Description
In the mathematical discipline of graph theory, a matching in a graph is a set of edges without common vertices.
You are given an undirected graph with n vertices, labeled by 1,2,...,n. Initially the graph has no edges.
There are 2 kinds of operations :
+ u v, add an edge (u,v) into the graph, multiple edges between same pair of vertices are allowed.
- u v, remove an edge (u,v), it is guaranteed that there are at least one such edge in the graph.
Your task is to compute the number of matchings with exactly k edges after each operation for k=1,2,3,...,n2. Note that multiple edges between same pair of vertices are considered different.
 

Input
The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.
In each test case, there are 2 integers n,m(2≤n≤10,nmod2=0,1≤m≤30000), denoting the number of vertices and operations.
For the next m lines, each line describes an operation, and it is guaranteed that 1≤u<v≤n.
 

Output
For each operation, print a single line containing n2 integers, denoting the answer for k=1,2,3,...,n2. Since the answer may be very large, please print the answer modulo 109+7.
 

Sample Input
1        
4 8    
+ 1 2
+ 3 4
+ 1 3
+ 2 4
- 1 2
- 3 4
+ 1 2
+ 3 4
 

Sample Output
1 0
2 1
3 1
4 2
3 1
2 1
3 1
4 2
 

Source
2018 Multi-University Training Contest 3
 

Recommend
chendu
 

Statistic | Submit | Discuss | Note

装压dp

+:操作很简单就是:dp[i]+=dp[i-(1<<u)-(1<<v)];

-:操作就想象成反的: dp[i]-=dp[i-(1<<u)-(1<<v)];拿总的减去用到用到u,v

类似于背包某个物品不能放;

#include <cstdio>
#include <cstring>
#include <iostream>
//#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
//#define mod 998244353
const int mod=1e9+7;

ll dp[1<<11];//dp[i]:i集合内点完全匹配的方案数
int bit[1<<11];//i的二进制的1个数;
ll ans[11];
int lowbit(int x) {return x&-x;}
int calc(int x)
{
    int res=0;
    while(x){res++;x=x-lowbit(x);}
    return res;
}
int main()
{
    for(int i=0;i<(1<<10);i++)
        bit[i]=calc(i);
    int T,n,m,u,v;
    char op[3];
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof dp);
        memset(ans,0,sizeof ans);
        dp[0]=1;
        while(m--)
        {
            scanf("%s%d%d",op,&u,&v);
            u--;v--;
            if(op[0]=='+')
            {
                for(int i=(1<<n)-1;i>0;i--)
                if(((1<<u)&i)&&((1<<v)&i))
                {
                    dp[i]+=dp[i-(1<<u)-(1<<v)];
                    ans[bit[i]]+=dp[i-(1<<u)-(1<<v)]; //对于i集合所有点的匹配,会对ans造成的影响
                    dp[i]=dp[i]%mod;
                    ans[bit[i]]=ans[bit[i]]%mod;
                }
            }
            
            else
            {
                for(int i=1;i<1<<n;i++)
                if(((1<<u)&i)&&((1<<v)&i))
                {
                    dp[i]-=dp[i-(1<<u)-(1<<v)];
                    ans[bit[i]]-=dp[i-(1<<u)-(1<<v)];
                    dp[i]=(dp[i]+mod)%mod;
                    ans[bit[i]]=(ans[bit[i]]+mod)%mod;
                }
            }
            for(int i=2;i<=n;i=i+2)
            {
                if(i!=2)
                    cout<<" ";
                printf("%lld",ans[i]);
                
                
            }
            cout<<endl;
            
        }
        
        
        
        
    }
    
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/2014slx/p/9397606.html