Cyclic Tour (最优二分匹配)

2023-11-08 11:38
文章标签 二分 匹配 最优 tour cyclic

本文主要是介绍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).

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 (最优二分匹配)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/369597

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3104 二分答案

题意: n件湿度为num的衣服,每秒钟自己可以蒸发掉1个湿度。 然而如果使用了暖炉,每秒可以烧掉k个湿度,但不计算蒸发了。 现在问这么多的衣服,怎么烧事件最短。 解析: 二分答案咯。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <c

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta

poj 3692 二分图最大独立集

题意: 幼儿园里,有G个女生和B个男生。 他们中间有女生和女生认识,男生男生认识,也有男生和女生认识的。 现在要选出一些人,使得这里面的人都认识,问最多能选多少人。 解析: 反过来建边,将不认识的男生和女生相连,然后求一个二分图的最大独立集就行了。 下图很直观: 点击打开链接 原图: 现图: 、 代码: #pragma comment(

poj 2112 网络流+二分

题意: k台挤奶机,c头牛,每台挤奶机可以挤m头牛。 现在给出每只牛到挤奶机的距离矩阵,求最小化牛的最大路程。 解析: 最大值最小化,最小值最大化,用二分来做。 先求出两点之间的最短距离。 然后二分匹配牛到挤奶机的最大路程,匹配中的判断是在这个最大路程下,是否牛的数量达到c只。 如何求牛的数量呢,用网络流来做。 从源点到牛引一条容量为1的边,然后挤奶机到汇点引一条容量为m的边

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。