[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=54859604

向大(hei)佬(e)势力学(di)习(tou)

二分图其实早就学了,可是无赖自己当初没好好听讲,变种就不说了,连匈牙利算法都不会。这次给了我一个好好复习改过自新的机会,既把匈牙利搞熟了,也算是理解了一些变种。

最小路径覆盖:

题意

用最少的出租车送完所有的乘客

将时间上可以接上的乘客连边

在一个图中,希望用最少的路径将所有点走遍,为什么 最小路径数=点总数-最大匹配 呢?

一张图,如果我们先暴力的各用一条路径把点覆盖

(拆点,连边表示可到达,虚线是假设的)



那么每多一个匹配,就可以少一个路径(车)。

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int oo=0x3f3f3f3f; int m,h[505],mm[505],tim[505],st[505][2],en[505][2];
int top,hh,head[1010];
struct Node{
int to,nxt;
}a[250010];
int vis[1010],girl[1010]; void adde(int fr,int to,int val){
hh++;
a[hh].to=to;
a[hh].nxt=head[fr];
}
int dis(int x){
return abs(st[x][0]-en[x][0])+abs(st[x][1]-en[x][1]);
}
int diss(int a,int b){
return abs(en[a][0]-st[b][0])+abs(en[a][1]-st[b][1]);
}
bool find(int x){//printf("/");
for(int i=head[x];i;i=a[i].nxt){//printf("he ");
int v=a[i].to;
if(!vis[v]){
vis[v]=1;
if(girl[v]==0||find(girl[v])){
girl[v]=x;
return true;
}
}
}
return false;
}
int hungary(){
int rt=0;
for(int i=1;i<=m;i++){
memset(vis,0,sizeof(vis));
if(find(i)) rt++;
}
return rt;
}
void solve(){
memset(a,0,sizeof(a));
memset(head,0,sizeof(head));
memset(girl,0,sizeof(girl));
scanf("%d",&m);
top=2*m+1;hh=1;
char str[10];
for(int i=1;i<=m;i++){
scanf("%s",str);
h[i]=(str[0]-'0')*10+(str[1]-'0');
mm[i]=(str[3]-'0')*10+(str[4]-'0');
tim[i]=h[i]*60+mm[i];//printf("tim[%d]=%d\n",i,tim[i]);
scanf("%d%d%d%d",&st[i][0],&st[i][1],&en[i][0],&en[i][1]);
}
for(int i=1;i<m;i++){
for(int j=i+1;j<=m;j++){
if(tim[i]+dis(i)+diss(i,j)<tim[j]){
adde(i,m+j,1);//printf("he ");
}
}
}
int ans=0;
ans=hungary();
printf("%d\n",m-ans);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
solve();
}
return 0;
}

最小点覆盖集:

最小点覆盖=最大匹配

为什么呢?假设还有一条边没有被覆盖,即它连的两个点都还没有被纳入匹配,那么这又是一个匹配了

题意

在n*n的方格中,放着一些东西。我有一个武器,每次可以清除一横排或一纵列,问最小使用次数

裸体一道,A的人太多了。然而对初学者来说,是开拓新思维。将行与列拆成两个点,两边即为一个点

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int N=10000+5; int n,k,r[N],c[N];
int head[3*N],end[6*N],nxt[6*N],hh=0;
int vis[3*N],girl[3*N]; void adde(int a,int b){
hh++;
end[hh]=b;
nxt[hh]=head[a];
head[a]=hh;
}
bool find(int u){
for(int i=head[u];i;i=nxt[i]){
int v=end[i];
if(!vis[v]){
vis[v]=1;
if(girl[v]==0||find(girl[v])){
girl[v]=u;
return true;
}
}
}
return false;
}
int hungary(){
int rt=0;
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));
if(find(i)) rt++;
}
return rt;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++){
scanf("%d%d",&r[i],&c[i]);
adde(r[i],c[i]+n);//建边注意
}
printf("%d",hungary());
return 0;
}

总结:

1、此次算是学懂了一些了,二分图的变通就在于构图上,其中拆点的思想尤为重要,还需多练

二分图变种之最小路径覆盖、最小点覆盖集【poj3041】【poj2060】的更多相关文章

  1. Antenna Placement POJ - 3020 二分图匹配 匈牙利 拆点建图 最小路径覆盖

    题意:图没什么用  给出一个地图 地图上有 点 一次可以覆盖2个连续 的点( 左右 或者 上下表示连续)问最少几条边可以使得每个点都被覆盖 最小路径覆盖       最小路径覆盖=|G|-最大匹配数 ...

  2. HDU 1151 Air Raid(最小路径覆盖)

    题目大意: 有n个城市,m条道路,城市的道路是单向.  现在我们的伞兵要降落在城市里,然后我门的伞兵要搜索所有道路.问我们最少占领多少个城市就可以搜索所有的道路了. 我们可以沿着道路向前走到达另一个城 ...

  3. POJ 3020 Antenna Placement【二分匹配——最小路径覆盖】

    链接: http://poj.org/problem?id=3020 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...

  4. POJ-1422 Air Raid---二分图匹配&最小路径覆盖

    题目链接: https://vjudge.net/problem/POJ-1422 题目大意: 有n个点和m条有向边,现在要在点上放一些伞兵,然后伞兵沿着图走,直到不能走为止 每条边只能是一个伞兵走过 ...

  5. Taxi Cab Scheme POJ - 2060 二分图最小路径覆盖

    Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coord ...

  6. P2764 最小路径覆盖问题 (最小点覆盖=顶点数-最大匹配)

    题意:最小路径覆盖 题解:对于一个有向图,最小点覆盖 = 顶点数 - 最大匹配 这里的最大匹配指的是将原图中每一个点拆成入点.出点, 每条边连接起点的出点和终点的入点 源点S连接每个点的出点,汇点T连 ...

  7. 【HDU3861 强连通分量缩点+二分图最小路径覆盖】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...

  8. POJ 1422 二分图(最小路径覆盖)

    Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7278   Accepted: 4318 Descript ...

  9. hdu 1151 Air Raid(二分图最小路径覆盖)

    http://acm.hdu.edu.cn/showproblem.php?pid=1151 Air Raid Time Limit: 1000MS   Memory Limit: 10000K To ...

随机推荐

  1. Leetcode 671.二叉树中第二小的节点

    二叉树中第二小的节点 给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0.如果一个节点有两个子节点的话,那么这个节点的值不大于它的子节点的值. 给出这样的一个二叉树 ...

  2. Windows 下开发.NET Core应用

    一.使用Visual Studio 2015开发1.1 依次安装Visual Studio 2015 Update 3.NET Core 1.0.0 - VS 2015 Tooling Preview ...

  3. 批量部署ssh免密登陆

    #!/bin/bash#set -xservers="10.254.192.xx10.254.192.xx10.254.192.xx"passwd="xxxxxxxx&q ...

  4. poj 3436 网络流构图经典

    ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6012   Accepted: 2 ...

  5. 关于jdk与jre的区别

    JDK:Java Development Kit JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程 ...

  6. SQL小助手——SQL Prompt

    背景: 当数据库设计的比较复杂.庞大时,我们如果对脚本不是很熟悉,就会很难完成看似简单的增.删.改.查的操作.我们需要一款软件来给出相应的提示或帮助,来提高代码的可读性,更快更好的完成任务. 简介: ...

  7. 【干货】2个小时教你hexo博客添加评论、打赏、RSS等功能 (转)

    备注:该教程基于Hexo 2.x版本,目前Hexo是3.x版本,照本教程实现有可能会出现404错误,笔者目前还未找时间去解决,待笔者找时间解决该问题后,再写一篇该问题的解决教程,给各位读者带来困扰,还 ...

  8. sql优化(转)

    explain +sql分析sql语句执行效率 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用! ...

  9. 【bzoj4894】天赋 矩阵树定理

    题目描述 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的.也就是说,有一些天赋必须是要在学习了另一个天赋 ...

  10. 【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流

    原文地址:http://www.cnblogs.com/GXZlegend/p/6832504.html 题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘 ...