hdu 4862 KM算法 最小K路径覆盖的模型
http://acm.hdu.edu.cn/showproblem.php?pid=4862
选t<=k次,t条路要经过全部的点一次而且只一次。
建图是问题:
我自己最初就把n*m 个点分别放入X集合以及Y集合,再求最优匹配,然后连例子都过不了,并且事实上当时解释不了什么情况下不能得到结果。由于k此这个条件相当于没用上。。。
建图方法:
1、X集合和Y集合都放入n*m+k个点,X中前n*m个点和Y中前n*m个点之间。假设格子里的值相等。权就是(收益-耗费),不等就是(-耗费),由于要的是最大收益,所以初始时。全部点之间权值为-1;
原因:例如以下图,1->2 2->3 3->1 二分图的边本身不和其它边相连,可是这种建图方式,使得能够找到连同路径1->2->3
由此学到的一种思维方式:二分图又称作二部图。是图论中的一种特殊模型。 设G=(V,E)是一个无向图。假设顶点V可切割为两个互不相交的子集(A,B),而且图中的每条边(i。j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B)。则称图G为一个二分图。可是假设两个子集是一样的。那么就能通过二分图的算法找路径或者连通分量
这样建图须要避免的是1->1,这样的自环的情况。导致有些点不能被覆盖,避免的方法就是初始化的时候,由于要的是最大收益。所以把自环的边初始化为最小值。
2、X中后k个点到Y中前n*m个点,权值为0。Y中后k个点到X中前n*m个点,权值也为0。增加的k个点是作为起点和终点,起点到第一个格子不须要耗费
3、X中k个点和Y中k个点一一相应的权值为0 由于同意少于k次把图遍历完毕。k个点中,有自环,说明这次不须要用
建图说的应该够清了,以后复习也好用
帖代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string> using namespace std; #define rep(i,s,e) for(int i=s;i<e;i++) const int INF = 999999;//
const int MAXN = 11*11+150;
int n,matv[MAXN][MAXN],mat[MAXN][MAXN],match[MAXN];
bool sx[MAXN],sy[MAXN];
int lx[MAXN],ly[MAXN];
char line[MAXN]; inline int ABS(int x)
{
return x>=0?x:-x;
} bool path(int u)
{
sx[u]=true;
rep(v,0,n)
if(!sy[v] && lx[u]+ly[v]==mat[u][v])
{
sy[v]=1;
if(match[v]==-1 || path(match[v]))
{
match[v]=u;
return true;
}
}
return false;
} int KM()
{
rep(i,0,n)
{
lx[i]=-INF;
ly[i]=0;
rep(j,0,n)
{
lx[i]=max(lx[i],mat[i][j]);
}
}
memset(match, 0xff, sizeof(match));
rep(u,0,n)
{
while(1)
{
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
if(path(u))break;
int dmin=INF;
rep(i,0,n)
if(sx[i])
rep(j,0,n)
if(!sy[j])
dmin=min(lx[i]+ly[j]-mat[i][j],dmin);
rep(i,0,n)
{
if(sx[i])
lx[i]-=dmin;
if(sy[i])
ly[i]+=dmin;
}
}
}
int sum=0;
rep(j,0,n)////
{
if(mat[match[j]][j] == -INF)return -INF;
sum+=mat[match[j]][j];
}
return sum;
} void init(int nn, int mm,int kk)
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
mat[i][j]=-INF;
}
rep(i,nn*mm,n)
mat[i][i]=0;
rep(i,0,nn)
rep(j,0,mm)
{
rep(ii,0,kk)
mat[nn*mm+ii][i*mm+j]=mat[i*mm+j][nn*mm+ii]=0;
//right
rep(jj,j+1,mm)
{
if(matv[i][j] == matv[i][jj])
{
mat[i*mm+j][i*mm+jj]=matv[i][j]-ABS(j-jj)+1;
}
else
{
mat[i*mm+j][i*mm+jj]=-ABS(j-jj)+1;
}
}
//below
rep(ii,i+1,nn)
{
if(matv[i][j] == matv[ii][j])
{
mat[i*mm+j][ii*mm+j]=matv[i][j]-ABS(i-ii)+1;//变量写错。。。 }
else
{
mat[i*mm+j][ii*mm+j]=-ABS(i-ii)+1;
}
}
}
} int main()
{
//freopen("hdu4862.txt","r",stdin);
//freopen("out.txt","w",stdout);
int ncase;
int nn,kk,mm;
scanf("%d",&ncase);
for(int icase=1;icase<=ncase;icase++)
{
scanf("%d%d%d",&nn,&mm,&kk);
n=nn*mm+kk;
rep(i,0,nn)
{
scanf("%s",line);
rep(j,0,mm)
{
matv[i][j]=line[j]-'0';
}
}
init(nn,mm,kk);
int ans=KM();
if(ans<=-INF)printf("Case %d : -1\n",icase);
else printf("Case %d : %d\n", icase, ans);
}
return 0;
}
hdu 4862 KM算法 最小K路径覆盖的模型的更多相关文章
- HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- hdu 3488(KM算法||最小费用最大流)
Tour Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))
Special Fish Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】
Consider a town where all the streets are one-way and each street leads from one intersection to ano ...
- P2172 [国家集训队]部落战争 二分图最小不相交路径覆盖
二分图最小不相交路径覆盖 #include<bits/stdc++.h> using namespace std; ; ; ; ], nxt[MAXM << ], f[MAXM ...
- Antenna Placement(匈牙利算法 ,最少路径覆盖)
Antenna Placement Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6991 Accepted: 3466 ...
- POJ Air Raid 【DAG的最小不相交路径覆盖】
传送门:http://poj.org/problem?id=1422 Air Raid Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- HDU 2255 KM算法 二分图最大权值匹配
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
随机推荐
- 【小技巧】树剖套线段树优化建图如何做到 O(nlogn)
前提:用树剖套线段树优化树链连边.例题:bzoj4699 我们说树剖的时间复杂度是 $O(n\times log(n))$,是因为访问一条链时需要经过 $log(n)$ 级别条重链,对于每条重链还需要 ...
- java读取文件的基本操作
import java.io.FileInputStream; /** * 使用FileInputStream读取文件 */ public class FileRead { /** * @param ...
- js数据类型判断
在一般情况下使用typeof 但是有时候typeof返回的结果都是object,比如数组和json对象的时候,这个时候需要用到 instanceof了 还有一个更好得办法,Object.prototy ...
- 《挑战程序设计竞赛》P196 铺砖问题
题意:给定n*m格子,每个格子被染成了黑色或者白色,现在要用1*2的砖块覆盖这些格子,块与块不得重叠,且覆盖所有的白色格子,但不覆盖任意一个黑色格子,求一共有多少种覆盖方法. 思路:书上给的思路太巧妙 ...
- JavaScript内部是这样运行
编译阶段 词法分析(Lexing) 这个过程会将由字符组成的字符串分解成(对编程语言来说)有意义的代码块,这些代 码块被称为词法单元(token). 简单举个例子:c = b - a 转换为 NAME ...
- JDBC连接池&DBUtils使用
使用连接池改造JDBC的工具类: 1.1.1 需求: 传统JDBC的操作,对连接的对象销毁不是特别好.每次创建和销毁连接都是需要花费时间.可以使用连接池优化的程序. * 在程序开始的 ...
- 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---14
以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:
- JavaScript闭包 循环输出i
html <body> <p>产品一</p> <p>产品二</p> <p>产品三</p> <p>产品四& ...
- JS-严格模式、非严格模式
2018年11月14日晚上,我在“深入理解javascript”书上第一次知道“严格模式”“非严格模式”这2个名词: “严格模式”使用指令:“use strict”: 这个指令我其实有经常看到,在其他 ...
- [Python Debug] How to install external python package? MAC系统下的xgboost安装
从昨天晚上开始安装xgboost,经历了各种稀奇古怪的错误,终于现在程序可以跑起来了.整个过程对python编译环境,路径设置,package安装方法有了一定了解,当然还有一些疑惑,所以姑且做个记录. ...