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<