杭电多校第三场1003 C. Dynamic Graph Matching(状压dp 处理图匹配计数)

Problem C. Dynamic Graph Matching

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


 

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

 

 

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   |   We have carefully selected several similar problems for you:  6331 6330 6329 6328 6327 

 

Statistic | Submit | Discuss | Note

【小结】

总碰到状压dp,总是束手无策。因为我菜。

【题意】

有一个n点的无向图,初始时没有边,有m次操作,每次可以增加或删除一条边(注意,允许重边的存在)

要求每一次操作之后,输出匹配数分别为1,2,3...n/2的方案数。

匹配是指:选中一些边,使得两两没有公共点,即每两个点可以通过边匹配起来。

【分析】

二进制表示集合,对于状态 i 的每一位,为1则选中,为0则不属于当前集合。

dp[i] 表示i状态,集合内所有点都匹配了 的 方案数。

那么当添加边u-v时,所有同时包含 uv 的状态 S 需要更新,dp[S] += dp[S-u-v]  (S-u-v表示状态S去掉u和v的状态)

更新dp[i] 时,需要考虑更新时会对答案产生的贡献。

【代码】

/****
***author: winter2121
****/
#include
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int MAX=2e5+5;

ll dp[1<<11]; //dp[i]:i集合内点完全匹配的方案数
int bit[1<<11]; //i的二进制的1的个数
ll ans[11];
void adjust(ll &x){x=(x%mod+mod)%mod;}
int calc(int x)
{
    int res=0;
    while(x)res++,x-=x&-x;
    return res;
}
int main()
{
    for(int i=0;i<1<<10;i++)bit[i]=calc(i);
    int T,n=10,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<0;i--)if(((1<

 

你可能感兴趣的:(ACM**动态规划**)