POJ-3041-建图/二分图匹配/网络流
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 26351 | Accepted: 14254 |
Description
Fortunately, Bessie has a powerful weapon that can vaporize all the asteroids in any given row or column of the grid with a single shot.This weapon is quite expensive, so she wishes to use it sparingly.Given the location of all the asteroids in the field, find the minimum number of shots Bessie needs to fire to eliminate all of the asteroids.
Input
* Lines 2..K+1: Each line contains two space-separated integers R and C (1 <= R, C <= N) denoting the row and column coordinates of an asteroid, respectively.
Output
Sample Input
3 4
1 1
1 3
2 2
3 2
Sample Output
2
Hint
The following diagram represents the data, where "X" is an asteroid and "." is empty space:
X.X
.X.
.X.
OUTPUT DETAILS:
Bessie may fire across row 1 to destroy the asteroids at (1,1) and (1,3), and then she may fire down column 2 to destroy the asteroids at (2,2) and (3,2).
Source
给出一个N*N的地图,和数个障碍物的位置(i,j) 每次操作可以将某一行或者某一列的障碍物都清楚,问最少的操作次数。
每一行/列缩一个点,对于每个(i,j),就把行i点和列j点连一条边,这样每一条边就对应着一个障碍物,操作转化为选取一个点之后,与这个点相连的边对应的障碍物都将被清除,问最少选出几个点能覆盖所有的边,又二分图中最小点覆盖=最大匹配数,所以就是求一个最大匹配。
这个题网络流也能解,按理说复杂度比匈牙利低,建图思路一样,行向列建边容量为1,源点向行点建边,列点向汇点建边跑最大流。
按理说树dp也可以求最小点覆盖但是一直WA不知为何= =
匈牙利:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
int match[],N;
bool vis[];
vector<int>g[];
int dfs(int u){
for(int i=;i<g[u].size();++i){
if(!vis[g[u][i]]){
vis[g[u][i]]=;
if(match[g[u][i]]==-||dfs(match[g[u][i]])){
match[g[u][i]]=u;
return ;
}
}
}
return ;
}
int main() {
int t,n,m,i,j;
scanf("%d%d",&n,&m);
for(i=;i<=n;++i)g[i].clear();
N=n;
while(m--){
scanf("%d%d",&i,&j);
g[i].push_back(j);
}
memset(match,-,sizeof(match));
int ans=;
for(i=;i<=n;++i){
memset(vis,,sizeof(vis));
ans+=dfs(i);
}
cout<<ans<<endl;
return ;
}
dinic:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdlib>
using namespace std;
#define inf 0x3f3f3f3f
struct Edge{
int v,cap,flow,next;
}e[];
int first[],tot,N;
int d[],cur[];
bool vis[];
void add(int u,int v,int cap){
e[tot].v=v;
e[tot].cap=cap;
e[tot].flow=;
e[tot].next=first[u];
first[u]=tot++;
}
bool bfs(){
memset(vis,,sizeof(vis));
queue<int>q;
q.push();
d[]=;
vis[]=;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=first[u];~i;i=e[i].next){
if(!vis[e[i].v] && e[i].cap>e[i].flow){
vis[e[i].v]=;
d[e[i].v]=d[u]+;
q.push(e[i].v);
}
}
}
return vis[N*+];
}
int dfs(int x,int a){
if(x==N*+ || a==) return a;
int flow=,f;
for(int &i=cur[x];~i;i=e[i].next){
if(d[x]+==d[e[i].v] && (f=dfs(e[i].v,min(a,e[i].cap-e[i].flow)))>){
e[i].flow+=f;
e[i^].flow-=f;
flow+=f;
a-=f;
if(a==) break;
}
}
return flow;
}
int solve(){
int ans=;
while(bfs()){
for(int i=;i<=N*+;++i)cur[i]=first[i];
ans+=dfs(,inf);
}
return ans;
}
int main(){
int m,i,j;
while(cin>>N>>m){
memset(first,-,sizeof(first));
tot=;
for(i=;i<=N;++i){
add(,i,);
add(i,,);
add(i+N,N*+,);
add(N*+,i+N,);
}
while(m--){
scanf("%d%d",&i,&j);
add(i,j+N,);
add(j+N,i,);
}
cout<<solve()<<endl;
}
return ;
}
POJ-3041-建图/二分图匹配/网络流的更多相关文章
- POJ 3041 Asteroids (二分图匹配)
[题目链接] http://poj.org/problem?id=3041 [题目大意] 一个棋盘上放着一些棋子 每次操作可以拿走一行上所有的棋子或者一列上所有的棋子 问几次操作可以拿完所有的棋子 [ ...
- POJ 2226 缩点建图+二分图最大匹配
这个最小覆盖但不同于 POJ 3041,只有横或者竖方向连通的点能用一块板子覆盖,非连续的,就要用多块 所以用类似并查集方法,分别横向与竖向缩点,有交集的地方就连通,再走一遍最大匹配即可 一开始还有点 ...
- LOJ 2548 「JSOI2018」绝地反击 ——二分图匹配+网络流手动退流
题目:https://loj.ac/problem/2548 如果知道正多边形的顶点,就是二分答案.二分图匹配.于是写了个暴力枚举多边形顶点的,还很愚蠢地把第一个顶点枚举到 2*pi ,其实只要 \( ...
- cogs_396_魔术球问题_(最小路径覆盖+二分图匹配,网络流24题#4)
描述 http://cojs.tk/cogs/problem/problem.php?pid=396 连续从1开始编号的球,按照顺寻一个个放在n个柱子上,\(i\)放在\(j\)上面的必要条件是\(i ...
- POJ 3057 Evacuation(二分图匹配+BFS)
[题目链接] http://poj.org/problem?id=3057 [题目大意] 给出一个迷宫,D表示门,.表示人,X表示不可通行, 每个门每时间单位只允许一个人通过, 每个人移动一格的为一时 ...
- POJ 3041 Asteroids (二分图最小点覆盖集)
Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24789 Accepted: 13439 Descr ...
- POJ 2724 Purifying Machine (二分图匹配)
题意 给定m个长度为n的01串(*既表示0 or 1.如*01表示001和101).现在要把这些串都删除掉,删除的方法是:①一次删除任意指定的一个:②如果有两个串仅有一个字符不同,则可以同时删除这两个 ...
- P3386 【模板】二分图匹配 -网络流版
二分图匹配 题目背景 二分图 感谢@一扶苏一 提供的hack数据 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+ ...
- poj 2226 Muddy Fields(合理建图+二分匹配)
/* 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 思路: 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩阵中只有0, 1 ...
随机推荐
- Basic Mathematics You Should Mastered
Basic Mathematics You Should Mastered 2017-08-17 21:22:40 1. Statistical distance In statistics, ...
- Python 安装与环境变量配置
一.软件下载 Python安装包下载地址:https://www.python.org/ 二.安装过程(略) 三.环境变量配置: 方法一:使用cmd命令添加path环境变量 在cmd下输入: path ...
- 测试与CMMI质量体系
1. CMMI全称是Capability Maturity Model Integration,即能力成熟度模型集成(也有称为:软件能力成熟度集成模型) 其目的是帮助软件企业对软件工程过程进行管理和改 ...
- 操作 html 的时候是使用 dom 方法还是字符串拼接?
比如一个列表里面有很多个 li,要给他们加上数据.但多少个 li 是不确定的,由后台数据确定.这时候,就要动态生成 html 内容了. 那么,这个过程, 是使用 += 方法把标签.数据进行一个个的字符 ...
- geoserver源码学习与扩展——自动发布shapefile图层
geoserver通过工作空间Workspace-数据源DataStore-图层Layer管理地理数据,这些信息都通过Catalog进行组织和管理,要完成自动发布只需要在Catalog中增加相应的信息 ...
- 设置电脑中的某个程序不弹出UAC用户控制提示的方法
有用户发现在电脑开机后总是会弹出UAC用户账户控制窗口,这是因为电脑中的某个程序设置了开机启动,这样就会在开机后启动该程序时出现UAC提示.如果想要省略该提示,可以在电脑中设置该程序不弹出UAC用户控 ...
- Kali Linux 更新源 操作完整版教程
一.查看kali系统的更新源地址文件 命令: vim /etc/apt/sources.list 上面这是kali官方的更新源: 拓展知识: 一个完整的源包括:deb 和 deb-src:上图源地址是 ...
- springboot之启动方式
我们在ideal中启动springboot项目时时不需要加载Tomcat容器的,直接在启动类启动就行了,原因是springboot项目中默认包含了内置Tomcat //springboot项目必须引入 ...
- QT---事件系统
1 QT事件系统 1.1 事件的定义 QT中事件是有专门的类QEvent,常见的有键盘事件QKeyEvent.鼠标事件QMouseEvent和定时器事件QTimerEvent.例如用 ...
- 动态规划-填格子问题 Domino and Tromino Tiling
2018-09-01 22:38:19 问题描述: 问题求解: 本题如果是第一看到,应该还是非常棘手的,基本没有什么思路. 不妨先从一种简化的版本来考虑.如果仅有一种砖块,那么,填充的方式如下.