Tour HDU - 3488(最大权值匹配)

Tour

In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one-way roads connecting them. You are lucky enough to have a chance to have a tour in the kingdom. The route should be designed as: The route should contain one or more loops. (A loop is a route like: A->B->……->P->A.) 
Every city should be just in one route. 
A loop should have at least two cities. In one route, each city should be visited just once. (The only exception is that the first and the last city should be the same and this city is visited twice.) 
The total distance the N roads you have chosen should be minimized.

InputAn integer T in the first line indicates the number of the test cases. 
In each test case, the first line contains two integers N and M, indicating the number of the cities and the one-way roads. Then M lines followed, each line has three integers U, V and W (0 < W <= 10000), indicating that there is a road from U to V, with the distance of W. 
It is guaranteed that at least one valid arrangement of the tour is existed. 
A blank line is followed after each test case.OutputFor each test case, output a line with exactly one integer, which is the minimum total distance.Sample Input

1
6 9
1 2 5
2 3 5
3 1 10
3 4 12
4 1 8
4 6 11
5 4 7
5 6 9
6 5 4

Sample Output

42

The route should contain one or more loops.

一个或多个环。。二分匹配足以。。  把权值取反 然后套最大权值匹配即可

注意有重边。。但我们是要最小值  取反后在输入的时候只保留max的值即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 220, INF = 0x7fffffff;
int usedx[maxn], usedy[maxn], cy[maxn], cx[maxn], w[maxn][maxn], bx[maxn], by[maxn];
int nx, ny, n, minn, min_val, m;
int dfs(int u)
{
    usedx[u] =1 ;
    for(int i=1; i<=ny; i++)
    {
        if(usedy[i] == -1)
        {
            int t = bx[u] + by[i] - w[u][i];
            if(t == 0)
            {
                usedy[i] = 1;
                if(cy[i] == -1 || dfs(cy[i]))
                {
                    cy[i] = u;
                    cx[u] = i;
                    return 1;
                }
            }
            else if(t > 0)
                minn = min(minn, t);
        }
    }
    return 0;
}

void km()
{
    mem(cy, -1);
    mem(cx, -1);
    for(int i=0; i<=nx; i++) bx[i] = -INF;
    mem(by, 0);
    for(int i=1; i<=nx; i++)
        for(int j=1; j<=ny; j++)
                bx[i] = max(bx[i], w[i][j]);
    for(int i=1; i<=nx; i++)
    {
        while(1)
        {
            minn = INF;
            mem(usedx, -1);
            mem(usedy, -1);
            if(dfs(i)) break;
            for(int j=1; j<=nx; j++)
                if(usedx[j] != -1) bx[j] -= minn;
            for(int j=1; j<=ny; j++)
                if(usedy[j] != -1) by[j] += minn;
        }
    }
    min_val = 0;
    for(int i=1; i<=nx; i++)
        if(cx[i] != -1)
            min_val += w[i][cx[i]];
    printf("%d\n",-min_val);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        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++)
        {
            int u, v, c;
            scanf("%d%d%d",&u,&v,&c);
                w[u][v] = max(w[u][v], -c);
        }
        nx = ny = n;
        km();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/WTSRUVF/p/9311819.html

时间: 2024-11-08 21:12:51

Tour HDU - 3488(最大权值匹配)的相关文章

hdu 1853 Cyclic Tour 最大权值匹配 全部点连成环的最小边权和

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1904    Accepted Submission(s): 951 Problem Description There are N cities in our c

hdu 1853 Cyclic Tour 最大权值匹配 所有点连成环的最小边权和

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1904    Accepted Submission(s): 951 Problem Description There are N cities in our c

HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 1 /*--------------------------------------------------------------------------------------*/ 2 3 #include <algorithm> 4 #include <iostream> 5 #include <cstring> 6 #include <ctype.h> 7 #include &l

Tour HDU - 3488

Tour HDU - 3488 可以用费用流做 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 const int maxv = 410; 5 const int maxe = maxv * maxv; 6 7 struct Edge{ 8 int u, v, cap, flow, cost; 9 int nxt; 10 Edge(int u = 0, int v = 0, in

二分图最大权值匹配 KM算法 模板

大佬讲的太好了!!!太好了!!! http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该博文服用更佳:趣写算法系列之--匈牙利算法 本文没有给出KM算法的原理,只是模拟了一遍算法的过程.另,博主水平较差,发现问题欢迎指出,谢谢!!!! 现在有N男N女,有些男生和女生之间互相有好感,我们将其好感程度定义为好感度,我们希望把他们两两配对,并且最后希望好感度和最大. 怎么选择最优的配对方法呢? 首先,每个女生会有一个期

Q - Tour - hdu 3488(最小匹配值)

题意:一个王国有N个城市,M条路,都是有向的,现在可以去旅游,不过走的路只能是环(至少也需要有两个城市),他们保证这些城市之间的路径都是有环构成的,现在至少需要走多少路. 分析:因为是有向图所以,而且走的是环所以每个城市都会进入一次并且出去一次,构成二分图,并且是完备匹配(完备匹配后肯定都是环了),现在只需要求出来这些匹配的最小值就行,可以把路径的值变为负数,然后求最大匹配值,最后的结果在变成相反数即可,注意路径可能有多条,输入的时候注意取最小的那个 **********************

POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格需花费$1(即单位费用=单位距离),一间house只能入住一个man.现在要求所有的man都入住house,求最小费用. 思路: KM算法传送门: 理解篇    运用篇 每个man和house建立带权二分图,曼哈顿距离就是边的值,这里要求最小费用,也就是二分图最小权值匹配,但是KM算法求的是二分图最

POJ 2195 Going Home 【二分图最小权值匹配】

传送门:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26151   Accepted: 13117 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit st

HDU 3488 Tour (最大权完美匹配)【KM算法】

<题目链接> 题目大意:给出n个点m条单向边边以及经过每条边的费用,让你求出走过一个哈密顿环(除起点外,每个点只能走一次)的最小费用.题目保证至少存在一个环满足条件. 解题分析: 因为要求包含所有点一次的环,我们不难发现,这个环中的每个点的出度和入度均为1,所以我们不妨将每个点进行拆点,将所有点的出度和入度分为两部分.因为该环需要包括所有的点,并且题目需要求该环的最小权值,相当于该带权二分图的每个点都需要被覆盖到,由于本题就转化为求该二分图的最优完美匹配问题.二分图的最优匹配问题求解,我们会想