zoukankan      html  css  js  c++  java
  • hdu

    题意:N个点,M条边的有向图,边有正权,求使每个点至少属于一个环的路径的最小权和(2 <= N <= 200,M <= 30000,0 < 每个边权W <= 10000)。

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3488

    ——>>好题~拆点的二分图最佳完美匹配。

    对于每一个顶点u,将其拆成u1和u2,若原来有一条边为u——>v,则变成u2——>v1,以xx2为X结点,xx1为Y结点,边权的相反数为权值(我们要求最小权和,二分图最佳完美匹配KM求的是最大权和,所以取边权的相反数作为权值,即可直接调用KM),跑一次KM,根据fa[](即选出来的路径)输出就好。不确定是否有重边的情况,为保险,插入权值时加个比较~偷笑

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 200 + 10;
    const int INF = 0x3f3f3f3f;
    
    int N, M, w[maxn][maxn], lx[maxn], ly[maxn], fa[maxn];
    bool S[maxn], T[maxn];
    
    bool match(int i){
        S[i] = 1;
        for(int j = 1; j <= N; j++) if(lx[i] + ly[j] == w[i][j] && !T[j]){
            T[j] = 1;
            if(!fa[j] || match(fa[j])){
                fa[j] = i;
                return 1;
            }
        }
        return 0;
    }
    
    void update(){
        int a = INF;
        for(int i = 1; i <= N; i++) if(S[i])
            for(int j = 1; j <= N; j++) if(!T[j])
                a = min(a, lx[i] + ly[j] - w[i][j]);
        for(int i = 1; i <= N; i++){
            if(S[i]) lx[i] -= a;
            if(T[i]) ly[i] += a;
        }
    }
    
    void KM(){
        for(int i = 1; i <= N; i++) fa[i] = lx[i] = ly[i] = 0;
        for(int i = 1; i <= N; i++)
            while(1){
                for(int j = 1; j <= N; j++) S[j] = T[j] = 0;
                if(match(i)) break;
                else update();
            }
    }
    
    void read(){
        int U, V, W;
        scanf("%d%d", &N, &M);
        for(int i = 1; i <= N; i++)
            for(int j = 1; j <= N; j++) w[i][j] = -INF;
        for(int i = 1; i <= M; i++){
            scanf("%d%d%d", &U, &V, &W);
            w[U][V] = max(w[U][V], -W);
        }
    }
    
    void solve(){
        int sum = 0;
        for(int i = 1; i <= N; i++) sum += w[fa[i]][i];
        printf("%d
    ", -sum);
    }
    
    int main()
    {
        int C;
        scanf("%d", &C);
        while(C--){
            read();
            KM();
            solve();
        }
        return 0;
    }
    


  • 相关阅读:
    Android开发之修改Manifest中meta-data的数据
    Android开发之StrictMode
    Cookie默认不设置path时,哪些请求会携带cookie数据
    Servlet中的请求转发
    AndroidCamera开发学习笔记01
    AsyncTask源码解读
    Android Studio自定义签名文件
    Kotlin:Android世界的Swift
    C# 传值给C++
    .NET CLR 运行原理
  • 原文地址:https://www.cnblogs.com/riskyer/p/3303811.html
Copyright © 2011-2022 走看看