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\n",-km());
    }
    return 0;
}

题意:

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

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

分析:

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

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

时间: 2024-08-29 16:18:17

HDU3488 Tour km的相关文章

HDU3488 Tour —— 二分图最大权匹配 KM算法

题目链接:https://vjudge.net/problem/HDU-3488 Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3720    Accepted Submission(s): 1777 Problem Description In the kingdom of Henryy, there are N (2 <=

Hdu 3488 Tour (KM 有向环覆盖)

题目链接: Hdu 3488 Tour 题目描述: 有n个节点,m条有权单向路,要求用一个或者多个环覆盖所有的节点.每个节点只能出现在一个环中,每个环中至少有两个节点.问最小边权花费为多少? 解题思路: 因为每个节点就出现一个,那么每个节点出度和入度都为1咯.我们可以对每个节点u拆点为u,u',分别放在集合X,Y.然后对两个集合进行完备匹配.完备匹配成功以后,每个节点就会有只有一个出度,一个入度的. 用KM求最小匹配的话,先初始化maps为-INF,然后把各边权值存为负,求出最大值取反即可. 1

HDU3488 Tour [有向环覆盖 费用流]

Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3159    Accepted Submission(s): 1525 Problem Description In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000

hdoj 3488 Tour 【最小费用最大流】【KM算法】

Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2299    Accepted Submission(s): 1151 Problem Description In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 3000

hdu1853 Cyclic Tour (二分图匹配KM)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others)Total Submission(s): 1688    Accepted Submission(s): 859 Problem Description There are N cities in our country, and M one-way roads connecting them. Now Li

最大流增广路(KM算法) HDOJ 1853 Cyclic Tour

题目传送门 1 /* 2 KM: 相比HDOJ_1533,多了重边的处理,还有完美匹配的判定方法 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3f3f; 12 int x

hdu 1853 Cyclic Tour &amp;&amp; hdu 3435 A new Graph Game(简单KM算法)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1478    Accepted Submission(s): 750 Problem Description There are N cities in our country, and M one-way roads connecting them. Now L

HDU 1853 Cyclic Tour(KM完美匹配)

HDU 1853 Cyclic Tour 题目链接 题意:一个有向图,边有权值,求把这个图分成几个环,每个点只能属于一个环,使得所有环的权值总和最小,求这个总和 思路:KM完美匹配,由于是环,所以每个点出度入度都是1,一个点拆成两个点,出点和入点,每个点只能用一次,这样就满足了二分图匹配,然后用KM完美匹配去就最小权值的匹配即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <

【二分图匹配入门专题1】M - Cyclic Tour hdu1853【km算法--判断自重边】

There are N cities in our country, and M one-way roads connecting them. Now Little Tom wants to make several cyclic tours, which satisfy that, each cycle contain at least two cities, and each city belongs to one cycle exactly. Tom wants the total len