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;
}

原文地址:https://www.cnblogs.com/2014slx/p/9397606.html

时间: 2024-08-11 11:00:51

hdu多校第3场C. Dynamic Graph Matching的相关文章

2018 HDU多校第三场赛后补题

2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube 题意: 在画布上画一个三维立方体. 题解: 模拟即可. 代码: #include <bits/stdc++.h> using namespace std; int a, b, c, R, C; char g[505][505]; int main () { int T; cin >>

2014 HDU多校弟八场H题 【找规律把】

看了解题报告,发现看不懂 QAQ 比较简单的解释是这样的: 可以先暴力下达标,然后会发现当前数 和 上一个数 的差值是一个 固定值, 而且等于当前数与i(第i个数)的商, 于是没有规律的部分暴力解决,有规律的套公式 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <cstring&g

2014 HDU多校弟九场I题 不会DP也能水出来的简单DP题

听了ZWK大大的思路,就立马1A了 思路是这样的: 算最小GPA的时候,首先每个科目分配到69分(不足的话直接输出GPA 2),然后FOR循环下来使REMAIN POINT减少,每个科目的上限加到100即可 算最大GPA的时候,首先每个科目分配到60分,然后FOR循环下来使REMAIN POINT减少,每个科目的上限加到85即可,如果还有REMAIN POINT,就FOR循环下来加到100上限即可 不会DP 阿 QAQ 过段时间得好好看DP了  =  = 于是默默的把这题标记为<水题集> //

2014 HDU多校弟五场J题 【矩阵乘积】

题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存开辟都开不出来 1 #pragma comment(linker, "/STACK:16777216") 2 #include <iostream> 3 #include <stdio.h> 4 #define ll long long 5 using namesp

2014 HDU多校弟五场A题 【归并排序求逆序对】

这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的方法,可以拿来当模板 TVT 贴代码了: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostream&g

2014 HDU多校弟六场J题 【模拟斗地主】

这是一道5Y的题目 有坑的地方我已在代码中注释好了 QAQ Ps:模拟题还是练的太少了,速度不够快诶 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <climits> #include <cstring> #include <cmath> #inclu

2018 Multi-University Training Contest 3 1003 / hdu6321 Problem C. Dynamic Graph Matching 状压dp

Problem C. Dynamic Graph Matching 题意: 给定一个n个点的无向图,m次加边或者删边操作.在每次操作后统计有多少个匹配包含k= 1,2,...,n2条边. 2≤n≤10,1≤m≤30000. Shortest judge solution: 770 bytes 题解: 设f[i][S]表示前i次操作之后,S集合的点已经匹配的方案数. 对于加边操作,显然f[i][S] =f[i?1][S] +f[i?1][S?u?v].i这一维可以省略,从大到小遍历S,f[S]+

hdu多校第4场 B Harvest of Apples(莫队)

Problem B. Harvest of Apples Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1600 Accepted Submission(s): 604 Problem Description There are n apples on a tree, numbered from 1 to n. Count the nu

hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测

题意: 给你一个1e9-1e14的质数P,让你找出这个质数的前一个质数Q,然后计算Q!mod P 题解: 1e9的数据范围pass掉一切素数筛法,考虑Miller-Rabin算法. 米勒拉宾算法是一种判断素数的随机化算法,由于其随机性,它不能保证总是正确的,但其对于一个素数,总会返回素数的结果,对于一个合数,才有极小概率返回素数的结果(假阳性). 米勒拉宾算法对于单个素数的判断时间复杂度为$O(log^3n)$.(因为1e14相乘会爆longlong,模乘要写成龟速乘,因此要多一个log) 18