本文主要是介绍Cyclic Tour (最优二分匹配),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853
题目大意:找几个环,保证环之间无公共点,并且保证找到的环权值最大;
题目思路:如果要保证图有环,并且环之间没有交点的话,那么必然每个点的出度和入度都应为1,因此我们可以把一个点拆成两个点,分别表示出度及入度,然后去找拆点后构成的二分图的完美匹配。也可以用网络流来做
题目:
Cyclic Tour
Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/65535K (Java/Other)
Total Submission(s) : 5 Accepted Submission(s) : 2
Problem 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).
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 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 6 5 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1
Sample Output
42 -1
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
const int MAXN=5000;
const int INF=0xfffffff;
int nx, ny, w[MAXN][MAXN], lx[MAXN], ly[MAXN];
int fx[MAXN], fy[MAXN], matx[MAXN], maty[MAXN];
char map[MAXN][MAXN];
int n,m;
struct node
{int x;int y;
} h[MAXN],man[MAXN];
int path(int u)
{fx[u] = 1;for (int v = 1; v <= ny; v++)if (lx[u] + ly[v] == w[u][v] && fy[v] < 0){fy[v] = 1;if (maty[v] < 0 || path(maty[v])){matx[u] = v;maty[v] = u;return 1;}}return 0;
}
void km()
{int i,j,k,ret = 0;memset(ly, 0, sizeof(ly));for (i = 1; i <= nx; i++){lx[i] = -INF;for (j = 1; j <= ny; j++)if (w[i][j] > lx[i]) lx[i] = w[i][j];}memset(matx, -1, sizeof(matx));memset(maty, -1, sizeof(maty));for (i = 1; i <= nx; i++){memset(fx, -1, sizeof(fx));memset(fy, -1, sizeof(fy));if (!path(i)){i--;int p = INF;for (k = 1; k <= nx; k++){if (fx[k] > 0)for (j = 1; j <= ny; j++)if (fy[j] < 0 && lx[k] + ly[j] - w[k][j] < p)p=lx[k]+ly[j]-w[k][j];}for (j = 1; j <= ny; j++)ly[j] += fy[j]<0 ? 0 : p;for (j = 1; j <= nx; j++)lx[j] -= fx[j]<0 ? 0 : p;}}/*for (i = 1; i <= ny; i++)ret += w[maty[i]][i];return ret;*/
}
void init()
{int a,b,c;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){w[i][j]=-INF;}}for(int i=0;i<m;i++){scanf("%d%d%d",&a,&b,&c);if(-c>w[a][b])w[a][b]=-c;}
}
int main()
{while(scanf("%d %d",&n,&m)!=EOF){init();nx=n;ny=n;km();bool flag=false;int ans=0;for(int i=1;i<=ny;i++){if(maty[i]==-1||w[maty[i]][i]==-INF){flag=true;break;}ans+=w[maty[i]][i];}if(!flag)printf("%d\n",-ans);else printf("-1\n");}return 0;
}
这篇关于Cyclic Tour (最优二分匹配)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!