进阶指南的板子好像有点问题。。交到hdu上会T

需要了解的一些概念:

  交错树,顶标,修改量

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define INF 99999999
#define maxn 305 int lx[maxn],ly[maxn];//顶标
int Match[maxn];//记录匹配值
int visx[maxn],visy[maxn];
int w[maxn][maxn];//权值
int slack[maxn];//slack为修改量
int ans,n; bool findPath(int x){
visx[x]=;
for(int y=; y<=n; y++){
if(visy[y])continue;
if(w[x][y]==lx[x]+ly[y]){//如果是相等子图则加入交错树中
visy[y]=;
if(!Match[y]||findPath(Match[y])){//增广后不用再考虑交错树
Match[y]=x;
return true;
}
}
else//不能加入交错树中的点,用来更新修改量
slack[y]=min(slack[y],lx[x]+ly[y]-w[x][y]);
}
return false;
}
void km(){
memset(Match,,sizeof(Match));
memset(lx,,sizeof(lx));
memset(ly,,sizeof(ly));
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
lx[i]=max(lx[i],w[i][j]); for(int x=; x<=n; x++){
for(int i=;i<=n;i++)slack[i]=INF;//初始化修改量
while(){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(findPath(x))break;//直到x找到一个匹配点时退出循环
//如果没找到匹配点(增广失败),那么找最小修改量,
int tmp=INF;
for(int i=;i<=n;i++){
if(!visy[i]){
if(tmp>slack[i])
tmp=slack[i];
}
}
//更新交错树中的顶标
for(int i=; i<=n; i++){
if(visx[i]) lx[i]-=tmp;
if(visy[i]) ly[i]+=tmp;else slack[i]-=tmp;
}
}
}
}
int main(){
while(scanf("%d",&n)!=EOF){
ans=;
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
scanf("%d",&w[i][j]);
km();
for(int i=; i<=n; i++)
ans+=w[Match[i]][i];
printf("%d\n",ans);
}
return ;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = ;
const double INF = 0xffffffffffff;
const double eps = 1e-; struct Node
{
double x,y;
}Dot1[MAXN],Dot2[MAXN]; double Dist(Node a,Node b)
{
return -sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} int N,NX,NY;
double Map[MAXN][MAXN];
int link[MAXN];
double lx[MAXN],ly[MAXN],slack[MAXN];
int visx[MAXN],visy[MAXN]; int FindPath(int u)
{
visx[u] = ;
for(int i = ; i <= NY; ++i)
{
if(visy[i])
continue;
double temp = lx[u] + ly[i] - Map[u][i];
if(fabs(temp) <= eps)
{
visy[i] = ;
if(link[i] == - || FindPath(link[i]))
{
link[i] = u;
return ;
}
}
else
{
if(slack[i] > temp)
slack[i] = temp;
}
}
return ;
} void KM()
{
memset(lx,,sizeof(lx));
memset(ly,,sizeof(ly));
memset(link,-,sizeof(link));
for(int i = ; i <= NX; ++i)
{
lx[i] = -INF;
for(int j = ; j <= NY; ++j)
if(Map[i][j] > lx[i])
lx[i] = Map[i][j];
} for(int i = ; i <= NX; ++i)
{
for(int j = ; j <= NY; ++j)
slack[j] = INF;
while()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(FindPath(i))
break;
double d = INF;
for(int j = ; j <= NY; ++j)
if(!visy[j] && d > slack[j])
d = slack[j];
for(int j = ; j <= NX; ++j)
if(visx[j])
lx[j] -= d;
for(int j = ; j <= NY; ++j)
{
if(visy[j])
ly[j] += d;
else
slack[j] -= d;
}
}
}
} int main()
{
int N;
while(~scanf("%d",&N))
{
memset(Map,,sizeof(Map));
for(int i = ; i <= N; ++i)
scanf("%lf%lf",&Dot1[i].x,&Dot1[i].y);
for(int i = ; i <= N; ++i)
scanf("%lf%lf",&Dot2[i].x,&Dot2[i].y); for(int i = ; i <= N; ++i)
for(int j = ; j <= N; ++j)
Map[i][j] = Dist(Dot1[i],Dot2[j]); NX = NY = N;
KM();
for(int i = ; i <= N; ++i)
{
for(int j = ; j <= N; ++j)
{
if(link[j] == i)
{
printf("%d\n",j);
break;
}
}
}
} return ;
}

带权二分图——KM算法hdu2255 poj3565的更多相关文章

  1. POJ3565带权匹配——km算法

    题目:http://poj.org/problem?id=3565 神奇结论:当总边权最小时,任意两条边不相交! 转化为求二分图带权最小匹配. 可以用费用流做.但这里学一下km算法. https:// ...

  2. KM(Kuhn-Munkres)算法求带权二分图的最佳匹配

    KM(Kuhn-Munkres)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...

  3. 运动员最佳匹配问题 KM算法:带权二分图匹配

    题面: 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势. ...

  4. HDU 2255 奔小康赚大钱(带权二分图最大匹配)

    HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...

  5. POJ 2195 Going Home (带权二分图匹配)

    POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...

  6. Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)

    Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配) Description 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的 ...

  7. Glorious Brilliance (最短路 + 带权二分图匹配)

    这是一道代码大题.一开始读错题意了,然后理解成直接看上去的那种相邻,然后想不通好久!!! 把不同联通的图分离出来,然后先预处理一下形成之后的相邻图的状态,然后根据01确定哪一些是需要更换状态的,然后建 ...

  8. [HAOI2008]移动玩具(状压&带权二分图)

    题目描述 • 一个 4 × 4 的 0/1 矩阵 • 每次可以交换相邻两个元素 • 求从初始状态到目标状态的最小交换次数 输入格式 前四行,每行一个长为 4 的 0/1 字符串,描述初始状态. 后四行 ...

  9. POJ 2195 Going Home | 带权二分图匹配

    给个地图有人和房子 保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价 问让人都住在房子里最小代价 显然是个带权二分图最大匹配 转化成以一个网络,规定w是容量,c是代价 1.S向人连边,w=1 ...

随机推荐

  1. 记录一次像github开源项目提交pull request(Hexo Next)

    文章目录 背景 fork到自己github 像往常一样的操作 克隆到本地 与上游建立连接 创建分支 修改项目代码 收尾工作 提交pull request 个人博客:https://mmmmmm.me ...

  2. jquery判断对象是undifined,判断对象是null

    判断对象是undifined: var aaa = undefined; if (typeof(aaa) == "undefined") { ... } typeof 返回的是字符 ...

  3. day26-多态、封装、反射

    #!/usr/bin/env python # -*- coding:utf-8 -*- # ----------------------------------------------------- ...

  4. 3步永久性激活IntelliJ IDEA 亲测有效

    1.进到文件夹中:C:\Windows\System32\drivers\etc ,找到hosts文件,用文本编辑器打开文件,将“  0.0.0.0 account.jetbrains.com ”添加 ...

  5. Java 并发工具包——ExecutorService常用线程池

    1. 执行器服务 ExecutorService java.util.concurrent.ExecutorService 接口表示一个异步执行机制,使我们能够在后台执行任务.因此一个 Executo ...

  6. 深夜Python - 第1夜 - for 迷 in 迷思

    深夜Python - 第1夜 - for 迷 in 迷思 在一个月黑风高的夜晚,我悄悄打开编辑器,进入程序的世界.刚刚学会Python的我,由于一段时间的过度装B,被委托优化一段程序,我信心十足地接下 ...

  7. 15-Ubuntu-文件和目录命令-查看目录内容-ls-2

    4. ls和通配符的使用 通配符适用的地方:shell命令行或者shell脚本中. 正则表达式适用的地方:字符串处理时,一般有一般正则和Perl正则. 正则表达式与通配符有相同的符号但是意义不同!! ...

  8. springboot中参数校验

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  9. 更改idea启动内存信息

    1.到idea的安装目录的bin下,找idea64.exe.vmoptions 文件 2.更改参数 对应的参数解释: -Xms1024m    设置IDEA初时的内存大小,提高Java程序的启动速度. ...

  10. C9 vs 三星

    我还是更喜欢 C9, 可惜当年的牛B人物 LemonNation 不在了,C9 赢 三星 一局的机会都没有了. 伟大的 LemonNation ,软件工程学硕士, 2014年,LemonNation ...