hdu 6321 Dynamic Graph Matching(dp)

本文介绍了一种使用动态规划算法解决图中匹配数量问题的方法,特别关注于如何通过加减边来更新匹配计数,包括1匹配、2匹配和3匹配的情况。文中详细解释了动态规划的状态转移方程,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出一个图,询问加减边,问你在当时的1匹配,2匹配,3匹配的种类有多种
2匹配=>该图中,选出两条边,连着四个点,完全不重叠的,其余同理
dp[S],S中的所有点,和某些边,是一个count1(S)/2的匹配
dap = 1<< u|1<< v
加边的时候 dp[S] += dp[S^dap] S^dap没有u和v的连边,加入之,(一维数组包括原来的)
注意减边的时候是dp[S] -= dp[S^dap]

#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cstring>
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
using namespace std;
typedef long long LL;
const int MAXN = 3e4+17;
const int MOD = 1e9+7;
int main()
{
#ifdef noob
    freopen("Input.txt", "r", stdin);
    freopen("Output.txt", "w", stdout);
#endif
    int t;
    cin>>t;
    int cnt[10000];
    for (int i = 0; i <= 1<<10; ++i)
    {
        cnt[i] = __builtin_popcount(i);
    }
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        vector<int > dp((1<<n)+1);
        dp[0] = 1;
        for(int i = 1; i <= m; i++)
        {
            char cmd[5];
            int u,v;
            scanf("%s%d%d",&cmd,&u,&v);
            u--,v--;
            int dap = (1<<u)|(1<<v);
            if(cmd[0]=='+')
            {
                for(int k = 0; k < 1<<n; k++)
                    if((k&dap)==dap) 
                        dp[k] = (dp[k]+dp[k^dap])%MOD;
            }
            else
            {
                for(int k = 0; k <= 1<<n; k++)
                    if((k&dap)==dap) 
                        dp[k] = (dp[k]-dp[k^dap]+MOD)%MOD;
            }
            vector<int > ans(6);
            for(int k = 0; k < 1<<n; k++)
            {
                if(cnt[k]%2==0)
                    ans[cnt[k]/2] = (ans[cnt[k]/2]+dp[k])%MOD;
            }
            for (int i = 1; i <= n/2; ++i)
            {
                printf("%lld%c",ans[i],i==n/2?'\n':' ' );
            }
        }

    }
    return 0;
}

注意减边的时候是dp[S] -= dp[S^dap] 首先,假设上一步就是加的这条要被现在删的边了,那么显然,在之前做这种调换,是没有影响的,那么,一定存在一种顺序,即上一步就是加这条边,在操作完之后是当前结果,即便事实不是这样.这里我很惊奇,仿佛是从虚空之中取出了这种顺序.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值