POJ_3565_Ants
题意:给出N个白点和N个黑点,要求用N条不相交的线段把它们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接到一条线段。
分析:因为有结点黑白两色,我们不难想到构造一个二分图,其中每个白点对应一个X结点,每个黑点对应一个Y结点,每个黑点和每个白点相连,权值等于二者的欧几里德距离。建模后最佳完美匹配就是问题的解。为什么呢?假设在最佳完美匹配中有两条线段a1-b1与a2-b2相交,那么dist(a1,b1)+dist(a2,b2)一定大于dist(a1,b2)+dist(a2,b1),因此如果把这两条改成a1-b2和a2-b1后总长度会变少,与最佳二字矛盾。
注意:KM算法是求权值和最大的,故需要将距离边成负数即可。并且输入坐标值好像是浮点的。
参考自:http://www.cnblogs.com/arbitrary/archive/2013/02/27/2936008.html
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define Del(x,y) memset(x,y,sizeof(x))
#define N 105
#define INF 999999999
struct Point
{
double x,y;
} point[N*]; double dis(Point a,Point b)
{
return sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
} double lx[N],ly[N]; //顶点标号
int link[N]; //存放与T点集连结的S点集里的点
int S[N],T[N]; //visit,是否属于相等子图
double w[N][N];
int n; bool match(int i) //匈牙利
{
S[i]=true;
for(int j=;j<=n;j++)
{
if(abs(lx[i]+ly[j]-w[i][j])<10e-&&!T[j])
{
T[j]=true;
if(link[j]==||match(link[j]))
{
link[j]=i;
return true;
}
}
}
return false;
} void update() //更新顶点标号
{
double a=INF;
for(int i=;i<=n;i++)
if(S[i])
for(int j=;j<=n;j++)
if(!T[j])
a=min(a,lx[i]+ly[j]-w[i][j]);
for(int i=;i<=n;i++)
{
if(S[i]) lx[i]-=a; //S集里的点-a
if(T[i]) ly[i]+=a; //T集里的点+a
} //其余所有点不变
} void KM()
{
for(int i=; i<=n; i++)
{
link[i]=lx[i]=ly[i]=;
for(int j=; j<=n; j++)
lx[i]=max(lx[i],w[i][j]);
}
for(int i=; i<=n; i++)
for(;;)
{
Del(S,);
Del(T,);
if(match(i))break;
else update();
}
} int ans[N]; int main()
{
scanf("%d",&n);
for(int i=; i<=n*; i++)
scanf("%lf%lf",&point[i].x,&point[i].y);
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
w[i][j]=-dis(point[i],point[j+n]);
KM();
for(int i=;i<=n;i++)
ans[link[i]]=i;
for(int i=;i<=n;i++)
printf("%d\n",ans[i]);
return ;
}
POJ_3565_Ants的更多相关文章
随机推荐
- PLU Decomposition
PLU分解的优点是,能够将Ax=b的矩阵,转换成Ly=b, Ux = y 的形式.当我们改变系数矩阵b时,此时因为矩阵L和U均是固定 的,所以总能高效的求出矩阵的解. // LU.cpp : Defi ...
- 使用adb在电脑和手机间传文件
首先须要root手机. 然后,"Win + R",打开cmd窗体.以下以copy d:\1.txt到/system/文件夹为例说明. adb push source(localpa ...
- Android处理日期
近期做一个项目,后台返回的日期是RFC3339格式的.之前没有看到过,当中遇到了几个问题以及解决 1.2015-11-18T14:49:55Z转换 在SimpleDateFormat中给出了几种格式 ...
- 00020970-0000-0000-C000-000000000046
00020970-0000-0000-C000-000000000046 System.InvalidCastException: 无法将类型为“Microsoft.Office.Interop.Wo ...
- 8-23 canvas专题
8-23 canvas专题-了解外部框架的使用 学习要点 掌握画布内容的导出的toDataURL()方法 了解外部框架的使用 第八章内容介绍 在第八章中我们将对以前的知识进行简单的回顾,着重对canv ...
- bzoj4869
http://www.lydsy.com/JudgeOnline/problem.php?id=4869 终于A了...参考了下dalao的代码... 拓展欧几里得定理,改了几次就不变了,但是用的时候 ...
- 移动端html touch事件
诸如智能手机和平板电脑一类的移动设备通常会有一(capacitive touch-sensitivescreen),以捕捉用户的手指所做的交互.随着移动网络的发展,其能够支持越来越复杂的应用,web开 ...
- maven pom 详细配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- 手机访问PC网站自动跳转到手机网站代码
方法一: <script type="text/javascript"> try { var urlhash = window.location.hash; if (! ...
- [App Store Connect帮助]六、测试 Beta 版本(3.2)管理测试员:邀请外部测试员
在您上传至少一个构建版本之后,您可以邀请外部测试员(您组织之外的人员)使用“TestFlight Beta 版测试”来测试您的 App.为了使您的构建版本可用于外部测试,请创建一个群组.添加构建版本, ...