HDU 1853 Cyclic Tour(二分图最优匹配:有向环覆盖)

来源:互联网 发布:android ddms源码 编辑:程序博客网 时间:2024/05/21 19:32

题意:给你一个N个点M条边的带权有向图,现在要你求这样一个值:该有向图中的所有顶点正好被1个或多个不相交的有向环覆盖.这个值就是 所有这些有向环的权值和. 要求该值越小越好.

思路我们把任意一个顶点i都分成两个,即i和i’. 如果原图存在i->j的边,那么二分图有i->j’的边,费用小把权值取负


#include<cstdio>#include<cstring>#include<algorithm>#define INF 1e9using namespace std;const int maxn=100+10;struct Max_Match{    int n,W[maxn][maxn];    int Lx[maxn],Ly[maxn];    bool S[maxn],T[maxn];    int left[maxn];    bool match(int i)    {        S[i]=true;        for(int j=1;j<=n;j++)if(Lx[i]+Ly[j]==W[i][j] && !T[j])        {            T[j]=true;            if(left[j]==-1 || match(left[j]))            {                left[j]=i;                return true;            }        }        return false;    }    void update()    {        int a=1<<30;        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;        }    }    int solve(int n)    {        this->n=n;        memset(left,-1,sizeof(left));        for(int i=1;i<=n;i++)        {            Lx[i]=Ly[i]=0;            for(int j=1;j<=n;j++) Lx[i]=max(Lx[i], W[i][j]);        }        for(int i=1;i<=n;i++)        {            while(true)            {                for(int j=1;j<=n;j++) S[j]=T[j]=false;                if(match(i)) break;                else update();            }        }        int ans=0;        for(int i=1;i<=n;i++)        {            if(W[left[i]][i]==-INF) return -1; //找不到            ans += W[left[i]][i];        }        return -ans;//注意这里返回的是负值    }}KM;int main(){    int n,m;    while(scanf("%d%d",&n,&m)==2)    {        for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            KM.W[i][j]=-INF;        while(m--)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            KM.W[u][v]=max(KM.W[u][v],-w);//可能存在重边        }        printf("%d\n",KM.solve(n));    }    return 0;}

Description

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 length of all the tours minimum, but he is too lazy to calculate. Can you help him? 
 

Input

There are several test cases in the input. You should process to the end of file (EOF). 
The first line of each test case contains two integers N (N ≤ 100) and M, indicating the number of cities and the number of roads. The M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from city A to city B, whose length is C. (1 ≤ A,B ≤ N, A ≠ B, 1 ≤ C ≤ 1000). 
 

Output

Output one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1. 
 

Sample Input

6 91 2 52 3 53 1 103 4 124 1 84 6 115 4 75 6 96 5 46 51 2 12 3 13 4 14 5 15 6 1
 

Sample Output

42-1

Hint

 In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42.          
 


0 0
原创粉丝点击