Uvalive3353 Optimal Bus Route Design 带权二分图匹配
题目描述:给出一个有向带权图,现在要求在图中找出若干个环,使得每个点恰好在一个环里,且所有环的距离之和最小,如果不能使每个点恰好在一个环里,输出"N"。
思路:
将每个点u拆成u和u'两个点,如果从u到v有一条权值为dist的边,那么就从u向v'连一条权值为dist的边,明显可以看出,现在的这个图是一个二分图。下面就是这个问题的关键——在这个二分图中,每一个完美匹配对应了原图中的一组互不相交且把每个点都囊括在内的环;反之也成立 ,即原图中的一组互不相交且把每个点都囊括在内的环正好对应了二分图中的一个完美匹配。为什么呢?因为在一组互不相交的环中,每个点的入度为一,出度为一;而在二分图的一个完美匹配中,一个点u的u对应一条边,u'对应一条边,即每个点u的入度为一,出度也为一,结论得证,因此,二分图中的一个完美匹配和原图中的一组互不相交的环一一对应。
分析到这里,做法就比较明朗了。原来是要求原图中的一组互不相交且把每个点都囊括在内的权值最小的环,现在就变成求一个权值最小的完美匹配,就是一个二分图带权匹配的问题。注意是最小匹配,每条边权应该取原来的相反数,不存在于图上的边设为-INF,跑二分图最大匹配就可以,跑完了结果取相反数,如果最终结果大于等于INF,就说明原图不存在完美匹配,那么输出“N”
理解:
这种转换如果是第一次见,似乎真的不太好想,见过一次之后就加以总结——二分图的一个匹配,对应于原图的一组互不相交的环,反之亦然
#include <bits/stdc++.h>
#define LL long long
#define mem(a , x) memset(a , x , sizeof(a))
using namespace std;
const int maxn = 100 + 5;
const int INF = 1e5;
int S[maxn] , T[maxn] , lx[maxn] , ly[maxn] , link[maxn] , slack[maxn];
int mp[maxn][maxn] , n;
int dfs(int u)
{S[u] = 1;for(int i = 1 ; i <= n ; i++){int d = lx[u] + ly[i] - mp[u][i];if(!T[i] && d == 0){T[i] = 1;if(link[i] == -1 || dfs(link[i])){link[i] = u;return 1;}}elseslack[i] = min(slack[i] , d);}return 0;
}
int KM()
{int res = 0;mem(link , -1);for(int i = 1 ; i <= n ; i++){lx[i] = -INF; ly[i] = 0;for(int j = 1 ; j <= n ;j++){lx[i] = max(lx[i] , mp[i][j]);}}for(int i = 1 ; i <= n ; i++){mem(S , 0); mem(T , 0);for(int j = 1 ; j <= n ; j++) slack[j] = INF;while(!dfs(i)){int d = INF;for(int j = 1 ; j <= n ;j++){if(!T[j] && slack[j] < d){d = slack[j];}}for(int j = 1 ; j<= n ; j++){if(S[j]){lx[j] -= d; S[j] = 0;}if(T[j]){ly[j] += d; T[j] = 0;}}}}for(int i = 1 ; i <= n ;i++){res += (lx[i] + ly[i]);}return res;
}
int main()
{while(scanf("%d" , &n) != EOF && n){for(int i = 1 ; i <= n ; i++){for(int j = 1 ;j <= n ;j++){mp[i][j] = -INF;}}int to , dis;for(int i = 1 ; i <= n ; i++){while(scanf("%d" , &to) && to){scanf("%d" ,&dis);mp[i][to] = -dis;}}int ans = -KM();if(ans > 10000) puts("N");else printf("%d\n" , ans);}return 0;
}
Uvalive3353 Optimal Bus Route Design 带权二分图匹配相关推荐
- UVALive 3353 Optimal Bus Route Design
UVALive 3353 Optimal Bus Route Design 二分图最大完美匹配 题目 题目给出一个带权有向图,找若干个圈,使得每个结点切好属于一个圈,并且所有圈的总长度最小,如果没有满 ...
- 【UVALive】 3353 Optimal Bus Route Design 费用流
传送门:[UVALive]3353 Optimal Bus Route Design 题目大意:给出一个n(n <= 100)个点的有向带权图,找若干个圈,使得每个结点恰好属于一个圈.要求总长度 ...
- 带权二分图匹配(最小费用最大流) 8.2牛客暑期多校训练营五 E
E.room | 时间限制:1 秒 | 内存限制:256M Nowcoder University has 4n students and n dormitories ( Four students ...
- HDU 1853 HDU 3488【有向环最小权值覆盖问题 】带权二分图匹配 KM算法
HDU 1853 & HDU 3488[有向环最小权值覆盖问题 ]最小费用最大流 In the kingdom of Henryy, there are N (2 <= N <= ...
- 【BZOJ4819】【SDOI2017】新生舞会(01分数规划,带权二分图匹配)
Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的 ...
- UVALive 3353 - Optimal Bus Route Design(二分图最小权匹配)
题目链接 https://cn.vjudge.net/problem/UVALive-3353 [题意] 给你n个点(n<=100)的有向带权图,你要找到n个有向环,使得每个点恰好属于一个环,要 ...
- UVA 1349 Optimal Bus Route Design (二分图最小权完美匹配)
恰好属于一个圈,那等价与每个点有唯一的前驱和后继,这让人想到了二分图, 把一个点拆开,点的前驱作为S集和点的后继作为T集,然后连边,跑二分图最小权完美匹配. 写的费用流..最大权完美匹配KM算法没看懂 ...
- UVALive - 3353 Optimal Bus Route Design(二分图最佳匹配)
题目大意:给出一个n个点的有向带权图,找若干个圈,使得每个节点恰好属于一个圈,要求总长度尽量小 解题思路:首先要在一个圈内,且只能在一个圈内,那么每个点的入度和出度要都为1,所以二分图就有了 接着连边 ...
- HDU 2255 奔小康赚大钱 带权二分图匹配 KM算法
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
最新文章
- python中的for A in B for i in range()
- python Celery 分布式任务队列快速入门
- 装配图中齿轮的画法_装配图的规定画法 和特殊画法
- java基础----线程
- Log4net数据表
- 切面是异步还是同步操作‘_细说JS异步发展历程
- [python] 之 函数简介
- datetime默认当前时间_简述Python培训之time和datetime的区别
- java list初始容量_java中快速创建带初始值的List和Map实例
- 【其他】vue项目集成富文本编辑器
- java基于springboot+vue学生考勤签到请假管理系统84y43
- python吃鸡透视_绝地求生仅需这个设置!让你的电脑自带透视!吃鸡到手软
- TLS 各种加密套件
- C语言实现巴特沃斯IIR滤波器
- 基于proteus的51单片机仿真实例五十七、定时器/计数器T0的定时实例
- C++ 在图片上打印文字并保存图片
- 程序员的十层楼(http://softwareblogs-zho.intel.com/2009/02/04/1071/)
- css3中的景深,3d,和动画效果
- 经典java程序源代码_【转】经典Java程序源代码(一)
- 【深度学习】TensorFlow系统架构和设计理念