丘比特的烦恼(Cupid.exe)

  随着社会的不断发展,人与人之间的感情越来越功利化。最近,爱神丘比特发现,爱情也已不再是完全纯洁的了。这使得丘比特很是苦恼,他越来越难找到合适的男女,并向他们射去丘比特之箭。于是丘比特千里迢迢远赴中国,找到了掌管东方人爱情的神——月下老人,向他求教。
  月下老人告诉丘比特,纯洁的爱情并不是不存在,而是他没有找到。在东方,人们讲究的是缘分。月下老人只要做一男一女两个泥人,在他们之间连上一条红线,那么它们所代表的人就会相爱——无论他们身处何地。而丘比特的爱情之箭只能射中两个距离相当近的人,选择的范围自然就小了很多,不能找到真正的有缘人。
  丘比特听了月下老人的解释,茅塞顿开,回去之后用了人间的最新科技改造了自己的弓箭,使得丘比特之箭的射程大大增加。这样,射中有缘人的机会也增加了不少。
  情人节(Valentine's day)的午夜零时,丘比特开始了自己的工作。他选择了一组数目相等的男女,感应到他们互相之间的缘分大小,并依此射出了神箭,使他们产生爱意。他希望能选择最好的方法,使被他选择的每一个人被射中一次,且每一对被射中的人之间的缘分的和最大。
  当然,无论丘比特怎么改造自己的弓箭,总还是存在缺陷的。首先,弓箭的射程尽管增大了,但毕竟还是有限的,不能像月下老人那样,做到“千里姻缘一线牵”。其次,无论怎么改造,箭的轨迹终归只能是一条直线,也就是说,如果两个人之间的连线段上有别人,那么莫不可向他们射出丘比特之箭,否则,按月下老人的话,就是“乱点鸳鸯谱”了。
  作为一个凡人,你的任务是运用先进的计算机为丘比特找到最佳的方案。

输入文件格式:
  输入文件第一行为正整数k,表示丘比特之箭的射程,第二行为正整数n(n<30),随后有2n行,表示丘比特选中的人的信息,其中前n行为男子,后n行为女子。每个人的信息由两部分组成:他的姓名和他的位置。姓名是长度小于20且仅包含字母的字符串,忽略大小写的区别,位置是由一对整数表示的坐标,它们之间用空格分隔。格式为Name x y。输入文件剩下的部分描述了这些人的缘分。每一行的格式为Name1 Name2 p。Name1和Name2为有缘人的姓名,p是他们之间的缘分值(p为小于等于255的正整数)。以一个End作为文件结束标志。每两个人之间的缘分至多只被描述一次。如果没有被描述,则说明他们缘分值为1。

输出文件格式:
  输出文件仅一个正整数,表示每一对被射中的人之间的缘分的总和。这个和应当是最大的。

输入样例(cupid.in):
2
3
0 0 Adam
1 1 Jack
0 2 George
1 0 Victoria
0 1 Susan
1 2 Cathy
Adam Cathy 100
Susan George 20
George Cathy 40
Jack Susan 5
Cathy Jack 30
Victoria Jack 20
Adam Victoria 15
End

输出样例(cupid.out):

65

KM的思想还是有点难,花了很多时间才搞明白。实际上就是一直不停Hungary,每一个左边的一定要匹配一个,(此处假设左边是男人,右边是女人)

一开始让每一个男人匹配自己最喜欢的女人,直到匹配失败,如果失败了,就降低要求(通过顶标来实现,即在左边标记过的点和右边未标记的点所连的边中找一条最大的,要使左右已标记的点的定标之和不变,又要降低左边已标记的点和右边未标记点的标号只差)(注意Hungary的原理是一定不破坏原来的关系,所以只会更优不会更差)

大概就是这个思路,只是要注意,此时标记访问的不仅是女人了,男人也要标记访问了,虽然标记的目的不完全相同。男女之间有边的条件是他们的定标之和等于“缘分”。

这道题其实很裸很简单的,只是有一个地方,如果两人的线段之间有点,就不能连边,我一开始以为只判断三点共线就行,其实必须在两点之间。有一个坑爹的就是,忽略大小写,一开始没有注意到。

(注意一定要满足左边的比右边的数量少,否则会死循环)

#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
#include <string>
#include <cstdio>
using std::cout;
using std::cin;
using std::map;
using std::string;
struct pos
{long i;long x;long y;
};const long inf = 0x7fff0000;
map<string,pos> folks;
pos folks2[70];
long fate[70][70];
long dist;long n;
long d;
long m[70];
bool v[70];
long l[70];bool km(long x)
{v[x] = true;//vxfor (long y=n+1;y<2*n+1;y++){if (!v[y]&&(l[x]+l[y]==fate[x][y]))//vy lx ly{v[y] = true;if (m[y]==0||km(m[y])){m[y] = x;return true;}}}return false;
}int main()
{freopen("cupid.in","r",stdin);freopen("cupid.ou","w",stdout);cin >> dist >> n;dist *= dist;for (long i=1;i<2*n+1;i++){long x;long y;string name;pos ptmp;cin >> x >> y >> name ;transform(name.begin(),name.end(),name.begin(),::toupper);ptmp.i = i;ptmp.x = x;ptmp.y = y;folks[name] = ptmp;folks2[i] = ptmp;}for (long i=1;i<n+1;i++){for (long j=n+1;j<2*n+1;j++){long x1 = folks2[i].x;long x2 = folks2[j].x;long y1 = folks2[i].y;long y2 = folks2[j].y;if (((y1-y2)*(y1-y2))+((x1-x2)*(x1-x2))>dist){fate[i][j]=-inf;continue;}//fate[i][j]=0fate[i][j]=1;//=fate[j][i]=1;for (long k=1;k<2*n+1;k++){if (k == i || k == j) continue;long x = folks2[k].x;long y = folks2[k].y;if (((x2-x1)*(y-y1)==(y2-y1)*(x-x1))&&((x2>x&&x>x1||x2<x&&x<x1)||(y2>y&&y>y1||y2<y&&y<y1))){fate[i][j]=-inf;//fate[j][i]=0;break;}}}}for (long i=1;i<n+1;i++)for (long j=n+1;j<2*n+1;j++)if (fate[i][j]==1){l[i]=1;continue;}while (1){string name1;string name2;long ff;cin >> name1;transform(name1.begin(),name1.end(),name1.begin(),::toupper);if (name1 == "END") break;cin >> name2 >> ff;transform(name2.begin(),name2.end(),name2.begin(),::toupper);long i1 = folks[name1].i;long i2 = folks[name2].i;if (i1 > i2){long tmp = i1;i1 = i2;i2 = tmp;}if (fate[i1][i2]>0)fate[i1][i2]=ff;//fate[i2][i1]=ff;if (fate[i1][i2]>l[i1])l[i1]=fate[i1][i2];}for (long k=1;k<n+1;k++){while (1){memset(v,0,sizeof(v));if (km(k)) break;d = inf;for (long i=1;i<n+1;i++)if (v[i])for (long j=n+1;j<2*n+1;j++)if (!v[j])if (l[i]+l[j]-fate[i][j]<d)d = l[i]+l[j]-fate[i][j];for (long i=1;i<n+1;i++)if (v[i]) l[i]-=d;for (long i=n+1;i<2*n+1;i++)if (v[i]) l[i]+=d;}}long ans = 0;for (long i=n+1;i<2*n+1;i++){ans += fate[m[i]][i];}cout << ans;return 0;
}

【二分图最佳匹配】丘比特的烦恼相关推荐

  1. POJ 2195 【二分图最佳匹配】.cpp

    题意: 有 n 个房子和 n 个人 每个人走一个单元你就要付 1$ 有什么办法可以让把所有人都分派到房子里 而花费最少 输入: 给出n m 表示该矩阵由n 行 m 列组成 然后给出一个n*m的图 . ...

  2. HDU - 奔小康赚大钱(二分图最佳匹配+KM)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  3. POJ365Ants_二分图最佳匹配

    https://blog.csdn.net/lianai911/article/details/44835659 题意: 在坐标系中有N只蚂蚁,N棵苹果树,给你蚂蚁和苹果树的坐标.让每只蚂蚁去一棵苹果 ...

  4. UVA-1045 - The Great Wall Game(二分图最佳匹配)

    题意:在一个n*n的棋盘上有n个棋子,要求通过移动棋子使棋子的排布满足以下情况之一:呈横行排列:呈纵行排列:呈对角线排列(有两条). 棋子移动一个单元格的费用为1,总费用为所有棋子的移动费用之和.求最 ...

  5. UVALive - 3353 Optimal Bus Route Design(二分图最佳匹配)

    题目大意:给出一个n个点的有向带权图,找若干个圈,使得每个节点恰好属于一个圈,要求总长度尽量小 解题思路:首先要在一个圈内,且只能在一个圈内,那么每个点的入度和出度要都为1,所以二分图就有了 接着连边 ...

  6. 二分图最佳匹配 KM算法 Hdu2255奔小康赚大钱 + Poj 3565 Ants

    2014-10-4 更新 在最下面增加了基于邻接表的模板 理论:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html http://philosci ...

  7. HDU 2255 二分图最佳匹配 模板题

    题目大意: 给定每一个人能支付的房子价值,每个人最多且必须拥有一套房子,问最后分配房子可得到的最大收益 抄了个别人的KM模板,就这样了... 1 #include <cstdio> 2 # ...

  8. UVA - 1045 The Great Wall Game(二分图最佳完美匹配)

    题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...

  9. 洛谷 P2756 飞行员配对方案问题 (二分图/网络流,最佳匹配方案)

    P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其 ...

最新文章

  1. 用linux写python_linux用什么写python
  2. php symfony框架,PHP-Symfony2全栈框架的停用组件
  3. 2019年上半年收集到的人工智能集成学习干货文章
  4. 如何利用远程桌面连接CentOS的Desktop版本
  5. 一种简便的ios图片加密方法-对图片进行base64编码
  6. Cloud Studio全文搜索功能介绍
  7. pl/sql中的赋值运算符_如何在SQL中使用AND / OR运算符?
  8. php获取站点的根目录和站点的根URL
  9. Python生成器实现及yield关键字
  10. error LNK2005: _DllMain@12 already defined in MSVC
  11. BP网络算法及其改进
  12. 剑指offer面试题[54]-表示数值的字符串
  13. uvalive 3938 Ray, Pass me the dishes! 线段树 区间合并
  14. 洛谷OJ P1036 选数
  15. 微信好友只有昵称没有微信号_没微信号能找到人吗 只有微信昵称怎么找人
  16. 英语后置定语语法归纳
  17. 可闭环、可沉淀、可持续的企业级数据赋能体系
  18. 【云原生】安全容器 Kata Containers
  19. java时区和时间的关系_Java 时间、日期与时区的关系
  20. 事物(Transaction)

热门文章

  1. 三维目标检测之ROS可视化
  2. python 在南京发展_南京和杭州,哪一座城市潜力大?
  3. Android摄像头 只拍摄SurfaceView预览界面特定区域内容(矩形框)---完整实现(原理 底层Surface
  4. FPGA驱动旋转编码器(Verilog)
  5. android手机慢,揭秘Android手机变慢的三大原因与对策
  6. 机器学习中在线学习、批量学习、迁移学习、主动学习的区别
  7. 单一职责原则是什么?
  8. 第一章:深度学习引言
  9. 室内电子地图-自定义室内地图-室内地图在线工具
  10. obs-studio 二次封装(十)SDK 中添加降噪模块