HDU - 6321 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): 2138    Accepted Submission(s): 872


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

 

题意:给定一个N个点的无向图,M次操作,添加或删除一条边,每一次操作以后,打印用1,2,...N/2条边构成的匹配数。

思路:因为N的范围很小,所以可以把点的枚举状态用二进制表示集合。用一维数组dp[S]表示二进制集合为S的点集的匹配数。每次加边操作,从大到小遍历集合(对后面的状态不产生影响),dp[S]+=dp[S-u-v](请细细品味这个状态转移);删边操作,从小到大遍历集合,dp[S]-=dp[S-u-v]。预处理出每个1024之内每个数对应二进制含有1的个数,每次记录答案就将每个dp[S]加到ans[S对应的二进制个数]中。

参考博客http://www.cnblogs.com/xiuwenli/p/9398342.html

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const LL mod=1e9+7;
const LL N=1e3+100;
LL dp[N],ans[15],cnt[N];
int main()
{
    LL T;
    scanf("%lld",&T);
    while(T--)
    {
        mem(dp,0);
        mem(ans,0);
        mem(cnt,0);
        dp[0]=1;
        LL n,m;
        char s[5];
        LL x,y;
        scanf("%lld%lld",&n,&m);
        LL k=1<>=1;
            }
        }
        while(m--)
        {
            scanf("%s%lld%lld",s,&x,&y);
            x--,y--;
            LL S=(1<

 

你可能感兴趣的:(2018多校联赛)