zoukankan      html  css  js  c++  java
  • 提高模拟赛Day8T2最大匹配

    提高模拟赛Day8T2最大匹配

    题目

    (n)个点(n-1)条边的连通图,求最大匹配及最大匹配数量.

    image-20211108102802629

    思路

    基础的树形DP.

    题目相当于从树上选出最多边,使得边没有公共点,求边数及方案数.

    (f_{i,0/1})表示在以(i)为根的子树中,(i)有(1)/没有(0)连边的 最大的边的数量.

    [f_{i,0}=sum_{jin S_i}max(f_{j,0},f_{j,1})\ f_{i,1}=1 + max_{jin S_i}Big( f_{j,0}+sum_{kin S_i,k eq j}max(f_{k,0},f_{k,1}) Big) ]

    其中(S_i)表示(i)的子节点的集合.

    (g_{i,0/1})表示方案数,转移方程略.

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int read() {
        int re = 0;
        char c = getchar();
        bool negt = false;
        while(c < '0' || c > '9')negt |= (c == '-') , c = getchar();
        while(c >= '0' && c <= '9')re = (re << 1) + (re << 3) + c - '0' , c = getchar();
        return negt ? -re : re;
    }
    
    typedef long long ll;
    const int N = 1e5 + 10;
    ll mod = 1e9 + 7;
    
    namespace Graph {
        struct Edge {
            int to , nxt;
        } ed[N * 2];
        int head[N];
    
        int cnt;
        void addedge(int u , int v) {
            ++cnt;
            ed[cnt].to = v , ed[cnt].nxt = head[u] , head[u] = cnt;
        }
        void initialize() {
            memset(ed , 0 , sizeof(ed));
            memset(head , 0 , sizeof(head));
            cnt = 0;
        }
    } // namespace Graph
    using Graph::ed;
    using Graph::head;
    using Graph::addedge;
    
    int OUTPUT_TYPE;
    int n;
    
    int f[N][2];
    ll g[N][2];
    
    ll inv(ll mul) {//逆元
        ll res = 1;
        int p = mod - 2;
        while(p) {
            if(p & 1)res = res * mul % mod;
            mul = mul * mul % mod;
            p >>= 1;
        }
        return res;
    }
    
    ll contri[N];
    void dfs(int x , int fa) {
        for(int i = head[x] ; i ; i = ed[i].nxt) {
            int to = ed[i].to;
            if(to == fa)continue;
            dfs(to , x);
            f[x][0] += max(f[to][0] , f[to][1]);
        }
        for(int i = head[x] ; i ; i = ed[i].nxt) {
            int to = ed[i].to;
            if(to == fa)continue;
            f[x][1] = max(f[x][1] , f[x][0] - max(f[to][0] , f[to][1]) + f[to][0] + 1 );
            g[x][1] = g[x][1] * g[to][0] % mod;
        }
        if(OUTPUT_TYPE == 2) {
            ll sum = 1;
            for(int i = head[x] ; i ; i = ed[i].nxt) {
                int to = ed[i].to;
                if(to == fa)continue;
                if(f[to][0] == f[to][1])    contri[to] = (g[to][0] + g[to][1]) % mod;
                else    contri[to] = (f[to][0] > f[to][1] ? g[to][0] : g[to][1]) % mod;
                sum = sum * contri[to] % mod;
            }
            g[x][0] = sum;
            for(int i = head[x] ; i ; i = ed[i].nxt) {
                int to = ed[i].to;
                if(to == fa)continue;
                if(f[x][1] == f[x][0] - max(f[to][0] , f[to][1]) + f[to][0] + 1 )
                    g[x][1] += sum * inv(contri[to]) % mod * g[to][0] % mod , g[x][1] %= mod;
            }
        }
    }
    void solve() {
        Graph::initialize();
        memset(f , 0 , sizeof(f));
        memset(g , 0 , sizeof(g));
        memset(contri , 0 , sizeof(contri));
    
        n = read();
        for(int i = 1 ; i < n ; i++) {
            int u = read() , v = read();
            addedge(u , v) , addedge(v , u);
        }
        dfs(1 , 0);
        if(OUTPUT_TYPE == 1)printf("%d
    " , max(f[1][0] , f[1][1]) );
        else {
            printf("%d %lld
    " , max(f[1][0] , f[1][1]) , (f[1][0] == f[1][1] ? g[1][0] + g[1][1] : (f[1][0] > f[1][1] ? g[1][0] : g[1][1])) % mod );
        }
    }
    int main() {
    	freopen("hungary.in" , "r" , stdin);
    	freopen("hungary.out" , "w" , stdout);
    	
        int T = read();
    	OUTPUT_TYPE = read();
        while(T--)solve();
        return 0;
    }
    
    
  • 相关阅读:
    VS和IE或者360兼容模式简单调试js方法
    sqlserver2008自动备份,自动删除较早的别分文件
    EasyUI合并行
    sqlserver导入excel的电话号码(身份证)变为科学计数解决方式
    文本框灰色文字提示,鼠标点击文字消失
    Asp.net MVC 中Controller返回值类型ActionResult
    SQL中CONVERT()转化函数的用法 字符串转日期
    死锁的简单实现
    生产者消费者问题
    [leecode]Implement strStr()
  • 原文地址:https://www.cnblogs.com/dream1024/p/15523136.html
Copyright © 2011-2022 走看看