Tour HDU

来源:互联网 发布:playclub捏脸详细数据 编辑:程序博客网 时间:2024/05/17 09:06
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.

Input
An 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.
Output
For each test case, output a line with exactly one integer, which is the minimum total distance.
Sample Input
16 91 2 52 3 53 1 103 4 124 1 84 6 115 4 75 6 96 5 4
Sample Output
42


单向图,让你找到某些环包含所有的点,使得花费最小。

这个题的意思其实就是让你一对一对的找,最终覆盖掉所有的点,最后让花费最小。

这样的话不就是个二分图吗,然后套最大权匹配模板

不同的是这里是找最小,那么把权值变为负的,最后再取负就可以了

注意::::::重边!!!

#include <stdio.h>#include <algorithm>#include <string.h>#include <iostream>using namespace std;const int N = 310;const int INF = 0x3f3f3f3f;int nx,ny;//两边的点数int g[N][N];//二分图描述int linker[N],lx[N],ly[N];//y中各点匹配状态,x,y中的点标号int slack[N];bool visx[N],visy[N];bool DFS(int x){    visx[x] = true;    for(int y = 1; y <= ny; y++)    {        if(visy[y])continue;        int tmp = lx[x] + ly[y] - g[x][y];        if(tmp == 0)        {            visy[y] = true;            if(linker[y] == -1 || DFS(linker[y]))            {                linker[y] = x;                return true;            }        }        else if(slack[y] > tmp)            slack[y] = tmp;    }    return false;}int KM(){    memset(linker,-1,sizeof(linker));    memset(ly,0,sizeof(ly));    for(int i = 1; i <=nx; i++)    {        lx[i] = -INF;        for(int j = 1; j <= ny; j++)            if(g[i][j] > lx[i])                lx[i] = g[i][j];    }    for(int x =1; x <= nx; x++)    {        for(int i = 1; i <= ny; i++)            slack[i] = INF;        while(true)        {            memset(visx,false,sizeof(visx));            memset(visy,false,sizeof(visy));            if(DFS(x))break;            int d = INF;            for(int i = 1; i <= ny; i++)                if(!visy[i] && d > slack[i])                    d = slack[i];            for(int i = 1; i <=nx; i++)                if(visx[i])                    lx[i] -= d;            for(int i = 1; i <= ny; i++)            {                if(visy[i])ly[i] += d;                else slack[i] -= d;            }        }    }    int res = 0;    for(int i = 1; i <=ny; i++)        if(linker[i] != -1)            res += g[linker[i]][i];    return res;}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n,m;        scanf("%d%d",&n,&m);        memset(g,-0x3f3f3f3f,sizeof(g));        for(int i=0; i<m; i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            w=-w;            if(w>g[u][v])            g[u][v]=w;        }        ny=nx=n;        printf("%d\n",-KM());    }    return 0;}




原创粉丝点击