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路径覆盖的模型的更多相关文章

  1. HDU 4862 Jump(最小K路径覆盖)

    输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...

  2. 网络费用流-最小k路径覆盖

    多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  3. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  4. hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))

    Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】

    Consider a town where all the streets are one-way and each street leads from one intersection to ano ...

  6. P2172 [国家集训队]部落战争 二分图最小不相交路径覆盖

    二分图最小不相交路径覆盖 #include<bits/stdc++.h> using namespace std; ; ; ; ], nxt[MAXM << ], f[MAXM ...

  7. Antenna Placement(匈牙利算法 ,最少路径覆盖)

    Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6991   Accepted: 3466 ...

  8. POJ Air Raid 【DAG的最小不相交路径覆盖】

    传送门:http://poj.org/problem?id=1422 Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  9. HDU 2255 KM算法 二分图最大权值匹配

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. Twitter如何在数千台服务器上快速部署代码?

    答案是:用BT,也就是你我应该都很熟悉的BitTorrent. 对于网站经营者.创业者来说,扩展性的问题是在网站流量成长过程中势必会面对的问题,如何建立一个具有扩展性的架构(scalable arch ...

  2. Bzoj1195 [HNOI2006]最短母串 [AC自动机]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  3. 调试UPX压缩的notepad

    @date: 2016/11/29 @author: dlive 0x01 运行时压缩 对比upx压缩前后的notepad可以看到如下特点 PE头的大小一样 节区名称改变(.text -> .U ...

  4. Oracle创建自增长主键

    Oracle主键常用的分为UUID和自增长int两种,下面简单说下各自的优缺点: UUID的优点 1.生成方便,不管是通过sys_guid() 还是java的uuid都能很方便的创建UUID. 2.适 ...

  5. CSU 1779: 错误的算法【矩阵/模拟】

    Description 有道题目是这样的: 输入一个 n 行 m 列网格,找一个格子,使得它所在的行和列中所有格子的数之和最大.如果答 案不唯一,输出任意解即可.比如,在下面的例子中,最优解是(1,3 ...

  6. Hadoop1和Hadoop2的区别是什么?

    [学习笔记] Hadoop1和Hadoop2的区别是什么?马 克-to-win @ 马克java社区:原来的Hadoop1的Mapreduce又管资源管理,又管数据处理和计算.而Hadoop2中的Ma ...

  7. 2016北京集训测试赛(十六)Problem B: river

    Solution 这题实际上并不是构造题, 而是一道网络流. 我们考虑题目要求的一条路径应该是什么样子的: 它是一个环, 并且满足每个点有且仅有一条出边, 一条入边, 同时这两条边的权值还必须不一样. ...

  8. centos 7 关闭firewalld开启iptables

    1: 关闭系统高级防火墙firewalld systemctl stop firewalld.service #停止firewall systemctl disable firewalld.servi ...

  9. 【IntelliJ IDEA】1.安装使用IntelliJ IDEA

    IntelliJ IDEA,初次接触,被赞许的收费版IDE环境. =================================================================== ...

  10. 真正解决 thinkphp 验证码 出错 无法显示 问题

    今天做到验证码这一块想到tp自带验证图片  大喜单鼓捣半天不出来 一直是个小 X 官方提示:如果无法显示验证码,请检查:² PHP是否已经安装GD库支持:²输出之前是否有任何的输出(尤其是UTF8的B ...