UVa 11419 SAM I AM

很神奇的方法……参悟中

 1 /**/
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 using namespace std;
 9 const int mxn=12000;
10 vector<int>e[mxn];
11 int link[mxn],vis[mxn];
12 bool mk[mxn];
13 int n,r,c;
14 void init(){
15     for(int i=1;i<mxn;i++)e[i].clear();
16     memset(link,0,sizeof link);
17 }
18 bool dfs(int x){
19     int i,j;
20     mk[x]=1;
21     for(i=0;i<e[x].size();i++){
22         int v=e[x][i];
23         if(!vis[v]){
24             vis[v]=1;
25             mk[v]=1;
26             if(!link[v] || dfs(link[v])){
27                 link[v]=x;
28                 link[x]=v;
29                 return 1;
30             }
31         }
32     }
33     return 0;
34 }
35 void path(){
36     int i,j;
37     memset(mk,0,sizeof mk);
38     for(i=1;i<=r;i++){
39         if(!link[i]){
40             memset(vis,0,sizeof vis);
41             dfs(i);
42         }
43     }
44     for(i=1;i<=r;i++){
45         if(!mk[i]){
46             printf(" r%d",i);
47         }
48     }
49     for(i=1;i<=c;i++){
50         if(mk[i+r]){
51             printf(" c%d",i);
52         }
53     }
54     printf("\n");
55     return;
56 }
57 int main(){
58     while(scanf("%d%d%d",&r,&c,&n) && r && c && n){
59         init();
60         int i,j;
61         int x,y;
62         for(i=1;i<=n;i++){
63             scanf("%d%d",&x,&y);
64             e[x].push_back(y+r);
65             e[y+r].push_back(x);
66         }
67         int ans=0;
68         for(i=1;i<=r;i++){//第一次匹配,算答案
69             memset(vis,0,sizeof vis);
70             if(dfs(i))ans++;
71         }
72         printf("%d ",ans);
73         path();//算路径
74     }
75     return 0;
76 }
时间: 2024-08-09 06:42:41

UVa 11419 SAM I AM的相关文章

uva 11419 SAM I AM (最小覆盖 K&#246;nig定理)

uva 11419 SAM I AM 题目大意:给出一个R×C的网格,网格上棉纺了一些目标.可以在网格外发射子弹,子弹会沿着垂直或水平方向飞行,并且打掉飞行路径上的所有目标.你的任务是计算出最少需要多少子弹,各从哪个位置发射,才能把所有目标全部打掉. 解题思路:K?nig定理:最小覆盖数等于最大匹配数.把目标所在的坐标,转化为XY结点,行看成X结点,列看成Y结点.那现在问题就变成了,如何选最少的结点,覆盖所有的边. 求最小覆盖的步骤大致如下:1)在右边找到一个未被匹配过的点,标记.2)走一条没被

UVA 11419 - SAM I AM(二分图匹配+最小点覆盖)

UVA 11419 - SAM I AM 题目链接 题意:给定一个棋盘,上面有一些目标,现在要放炮,一个炮能打一行或一列,问最少放几个炮及放炮位置 思路:首先是二分图匹配,每个目标行列建边,做二分图匹配就是最少的放炮位置,至于输出方案,利用最小点覆盖的Konig原理去做,详细证明 代码: #include <cstdio> #include <cstring> #include <vector> using namespace std; const int N = 10

UVA 11419 SAM I AM (二分图,最小割)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2414 Problem C SAM I AM Input: Standard Input Output: Standard Output The world is in great danger!! Mental's forces have returned to Earth to eradi

UVa 11419 SAM I AM (最小覆盖数)

题意:给定一个 n * m 的矩阵,有一些格子有目标,每次可以消灭一行或者一列,问你最少要几次才能完成. 析:把 行看成 X,把列看成是 Y,每个目标都连一条线,那么就是一个二分图的最小覆盖数,这个答案就是二分图的最大匹配,在输出解的时候,就是从匈牙利树上,从X的未盖点出发,然后标记X和Y,最后X中未标记的和Y标记的就是答案. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdi

训练指南 UVA - 11419(二分图最小覆盖数)

layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 最小点覆盖 - 图论 - 训练指南 SAM I AM UVA - 11419 题目大意:给出一个R×C的网格,网格上棉纺了一些目标.可以在网格外发射子弹,子弹会沿着垂直或水平方向飞行,并且打掉飞行路径上的所有目标.你的任务是计算出最少需要多少子弹,各从哪个位置发射,才

Uva 11419 我是SAM

题目链接:https://vjudge.net/problem/UVA-11419 题意:一个网格里面有一些目标,可以从某一行,某一列发射一发子弹,可以打穿: 求最少的子弹,和在哪里打? 分析: 听说可以用吗MCMF做,没多想: 一个目标,拆成两个点,X,Y,X与Y之间连一条边,现在,在这些点里面选出一些点,使得每一条边都有一个端点被覆盖,这就是最小点覆盖=最大匹配(证明在之前写过,博客里可以找到,证明很有意思): 然后还要找出哪些被覆盖了: 1 // UVa11419 SAM I AM 2 /

UVa 11419 我是SAM(最小点覆盖+路径输出)

https://vjudge.net/problem/UVA-11419 题意:一个网格里面有一些目标,可以从某一行,某一列发射一发子弹,可以打掉它:求最少的子弹,和在哪里打? 思路: 每个点的x坐标与y坐标相连,现在就是要找一个最小点覆盖,同时还要输出哪些点被覆盖了. 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 using nam

uva 11419 最大匹配(最小点覆盖)

链接:https://vjudge.net/problem/27475 题意:给定一个二维矩阵,在一些格子里放置了东西,然后你有一门炮,每次能横向或纵向开一炮,将这一行所有的东西摧毁.问你最少花多少炮弹摧毁所有的东西?并输出一组解. 题解: 很久之前做的题目了,今天在看到的时候还是很有新的体会的.这是一个求最小覆盖的问题,最小点覆盖,将行列的每个点看作是x,y集合,将放置的东西的地方看作是边(大白书).然后求一次最大匹配,会得出来至少有多个点是不在同一行和同一列的,这样剩余的东西就会与原来的已匹

uva 11419 (二分图最小覆盖)

二分图最小覆盖数=最大匹配数 建模后即可 #include<cstdio>#include<cstring>#include<algorithm>using namespace std; struct my{   int next;   int v;}; const int maxn=1000000+10;const int maxn2=1000+5;my bian[maxn];int adj[maxn];int s[maxn2];int t[maxn2];int n,