二分图变种之最小路径覆盖、最小点覆盖集【poj3041】【poj2060】
[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】的更多相关文章
- Antenna Placement POJ - 3020 二分图匹配 匈牙利 拆点建图 最小路径覆盖
题意:图没什么用 给出一个地图 地图上有 点 一次可以覆盖2个连续 的点( 左右 或者 上下表示连续)问最少几条边可以使得每个点都被覆盖 最小路径覆盖 最小路径覆盖=|G|-最大匹配数 ...
- HDU 1151 Air Raid(最小路径覆盖)
题目大意: 有n个城市,m条道路,城市的道路是单向. 现在我们的伞兵要降落在城市里,然后我门的伞兵要搜索所有道路.问我们最少占领多少个城市就可以搜索所有的道路了. 我们可以沿着道路向前走到达另一个城 ...
- POJ 3020 Antenna Placement【二分匹配——最小路径覆盖】
链接: http://poj.org/problem?id=3020 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...
- POJ-1422 Air Raid---二分图匹配&最小路径覆盖
题目链接: https://vjudge.net/problem/POJ-1422 题目大意: 有n个点和m条有向边,现在要在点上放一些伞兵,然后伞兵沿着图走,直到不能走为止 每条边只能是一个伞兵走过 ...
- Taxi Cab Scheme POJ - 2060 二分图最小路径覆盖
Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coord ...
- P2764 最小路径覆盖问题 (最小点覆盖=顶点数-最大匹配)
题意:最小路径覆盖 题解:对于一个有向图,最小点覆盖 = 顶点数 - 最大匹配 这里的最大匹配指的是将原图中每一个点拆成入点.出点, 每条边连接起点的出点和终点的入点 源点S连接每个点的出点,汇点T连 ...
- 【HDU3861 强连通分量缩点+二分图最小路径覆盖】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...
- POJ 1422 二分图(最小路径覆盖)
Air Raid Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7278 Accepted: 4318 Descript ...
- hdu 1151 Air Raid(二分图最小路径覆盖)
http://acm.hdu.edu.cn/showproblem.php?pid=1151 Air Raid Time Limit: 1000MS Memory Limit: 10000K To ...
随机推荐
- 不吹不擂,你想要的Python面试都在这里了【315+道题】+精心整理的解答
Part01-Py基础篇(80) Part02-网络编程和并发(34) Part03-数据库和缓存(46) Part04-前端框架和其他(155) Part01-Py基础篇(80) 1.为什么学习Py ...
- python学习笔记-基础
1.大小写敏感 2. print (n,f,s1,s2,s3,s4,sep='\n') -- 换行输出 seq='\n' print ('n=%d'%n,'f=%f'%f,'s1=%s'%s1,' ...
- linux shell 总结 (整理)
ls /usr/bin/ info #路径操作 dirname basename #“”和‘’与 ` ` 在shell变量中的区别 “ ” 允许通过$符引用其他变量 ‘’禁止引用其他变量符,视为普通字 ...
- (原)UE4.20 自定义编辑器 - 基础(一)创建编辑器模块
@author:白袍小道 前言: 本小文参考了UnrealC++,游戏编辑器(应该都找不到了嘿嘿)等书籍. 引擎基于UnrealEngine4.20版本(由于UnrealC++ 用的是 ...
- html span和div的区别
div与span区别及用法 div与span区别及用法 DIV与SPAN区别及div与san用法篇 接下来了解在div+css开发的时候在html网页制作,特别是标签运用中div和span的区别及用法 ...
- [ecmanget][常用标签]bookmark
Bookmarks Bookmarks 书签栏 redis Try RedisRedisRedis应用2-Redis实现开发者头条页面点赞功能 - noaman_wgs的博客 - CSDN博客wind ...
- PAT 1075 链表元素分类
https://pintia.cn/problem-sets/994805260223102976/problems/994805262953594880 给定一个单链表,请编写程序将链表元素进行分类 ...
- B-Tree索引和Hash索引的区别
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...
- 【bzoj1899】[Zjoi2004]Lunch 午餐 dp
题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...
- BZOJ2125 最短路 【仙人掌最短路】
题目 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. 输入格式 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一 ...