zoukankan      html  css  js  c++  java
  • HDU3488 Tour km

    /* ***********************************************
    Author        :devil
    Created Time  :2016/5/25 17:22:34
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    using namespace std;
    const int N=201;
    const int inf=0x3f3f3f3f;
    int w[N][N];
    int lx[N],ly[N];
    int link[N];
    int visx[N],visy[N];
    int slack[N];
    int n;
    bool dfs(int u)
    {
        visx[u]=1;
        for(int v=1;v<=n;v++)
        {
            if(visy[v]) continue;
            int tmp=lx[u]+ly[v]-w[u][v];
            if(!tmp)
            {
                visy[v]=1;
                if(link[v]==-1||dfs(link[v]))
                {
                    link[v]=u;
                    return 1;
                }
            }
            else if(slack[v]>tmp) slack[v]=tmp;
        }
        return 0;
    }
    int km()
    {
        memset(link,-1,sizeof(link));
        memset(ly,0,sizeof(ly));
        for(int i=1;i<=n;i++)
        {
            lx[i]=w[i][1];
            for(int j=2;j<=n;j++)
                lx[i]=max(lx[i],w[i][j]);
        }
        for(int x=1;x<=n;x++)
        {
            memset(slack,inf,sizeof(slack));
            while(1)
            {
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                if(dfs(x)) break;
                int d=inf;
                for(int i=1;i<=n;i++)
                    if(!visy[i]&&d>slack[i])
                        d=slack[i];
                for(int i=1;i<=n;i++)
                {
                    if(visx[i]) lx[i]-=d;
                    if(visy[i]) ly[i]+=d;
                    else slack[i]-=d;
                }
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)
            if(link[i]>-1)
                ans+=w[link[i]][i];
        return ans;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        int t,m,x,y,p;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            memset(w,-inf,sizeof(w));
            while(m--)
            {
                scanf("%d%d%d",&x,&y,&p);
                w[x][y]=max(w[x][y],-p);
            }
            printf("%d
    ",-km());
        }
        return 0;
    }

    题意:

    有N个城市,M条街道,每条街道是单向的,现在要你设计多条路线覆盖所有的点,

    每条路线都是一个环,并且每个点仅能被一条路线覆盖且只经过一次(终始点除外)

    分析:

    因为是有向圈,所以每个点的入度和出度应该都是1,故将一个点拆成两个点,

    入度点和出度点,然后用最佳匹配即可!(因为最佳匹配是求最大值,故我们把边权设为负值即可!)

  • 相关阅读:
    知识点--Alzheimer disease
    基因组关联分析技术的简介
    数量遗传与植物育种—李慧慧
    windows下的python安装pysam报错
    【数据库】本地NR数据库如何按物种拆分?
    【数据库】本地KEGG数据库如何拆分子库?
    国内育种服务商
    【机器学习与R语言】13- 如何提高模型的性能?
    【机器学习与R语言】12- 如何评估模型的性能?
    【机器学习与R语言】11- Kmeans聚类
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5527815.html
Copyright © 2011-2022 走看看