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 eradicate humankind. Our last hope to stop this great evil is Sam “Serious” Stone. Equipped with various powerful weapons, Serious Sam starts his mission
to destroy the forces of evil.

After fighting two days and three nights, Sam is now in front of the temple KOPTOS where Mental‘s general Ugh Zan III is waiting for him. But this time, he has a serious problem. He is in shortage of ammo and a lot of enemies crawling inside the temple waiting
for him. After rounding thetemple Sam finds that the temple is in rectangle shape and he has the locations of all enemies in the temple.

All of a sudden he realizes that he can kill the enemies without entering
the temple using the great cannon ball which spits out a gigantic ball bigger than him killing anything it runs into and keeps on rolling until it finally explodes. But the cannonball can only shoot horizontally or vertically and all the enemies along the
path of that cannon ball will be killed.

Now he wants to save as many cannon balls as possible for fighting with Mental. So, he wants to know the minimum number of cannon balls and the positions from which he can shoot the cannonballs to eliminate all enemies from outside that temple.

 

Input

Here, the temple is defined as a RXC grid. The first line of each test case contains 3 integers: R(0<R<1001), C(0<C<1001) representing the grid of temple (R means number of row and C means number of column of the grid) and the number of enemies N(0<N<1000001)
inside the temple. After that there are N lines each of which contains 2 integers representing the position of the enemies in that temple. Each test case is followed by a new line (except the last one). Input is terminated when R=C=N=0. The size of the input
file is around 1.3 MB.

Output

For each test case there will be one line output. First print the minimum number (m) of cannonballs needed to wipe out the enemies followed by a single space and then m positions from which he can shoot
those cannonballs. For shooting horizontally print “r” followed by the row number and for vertical shooting print “c” followed by the column number. If there is more than one solution any one will do.

 

Sample Input                               Output for Sample Input


4 4 3

1 1

1 4

3 2

4 4 2

1 1

2 2

0 0 0


2 r1 r3

2 r1 r2


Problemsetter: Syed Monowar Hossain

Special Thanks: Derek Kisman

题意:

R×C的矩阵中有N个目标,每次可消除一行或一列,求最少消除次数及其方案,多种方案输出任意一种。

分析:

显然的二分图最小覆盖,可用网络流来解。源点到每一行连一条容量为1的边,每一列到汇点连一条容量为1的边,每个目标对应行列之间的一条容量为1的边,其最小割就是方案。

最小割显然可以用最大流来解,找最后的最小割还需要在残留网络中跑一边DFS,将S部和T部分开。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cctype>
#include<cmath>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<map>
#include<set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10
#define maxm 2500007
#define maxn 2007

using namespace std;

int fir[maxn];
int u[maxm],v[maxm],cap[maxm],flow[maxm],nex[maxm];
int e_max;
int lv[maxn],iter[maxn],q[maxn];

void add_edge(int _u,int _v,int _w)
{
    int e;
    e=e_max++;
    u[e]=_u;v[e]=_v;cap[e]=_w;
    nex[e]=fir[u[e]];fir[u[e]]=e;
    e=e_max++;
    u[e]=_v;v[e]=_u;cap[e]=0;
    nex[e]=fir[u[e]];fir[u[e]]=e;
}

void dinic_bfs(int s)
{
    int f,r;
    memset(lv,-1,sizeof lv);
    lv[s]=0;
    q[f=r=0]=s;
    while (f<=r)
    {
        int x=q[f++];
        for (itn e=fir[x];~e;e=nex[e])
        {
            if (cap[e]>flow[e] && lv[v[e]]<0)
            {
                lv[v[e]]=lv[u[e]]+1;
                q[++r]=v[e];
            }
        }
    }
}

int dinic_dfs(int _u,int t,int _f)
{
    if (_u==t)  return _f;
    for (int &e=iter[_u];~e;e=nex[e])
    {
        if (cap[e]>flow[e] && lv[u[e]]<lv[v[e]])
        {
            int _d=dinic_dfs(v[e],t,min(_f,cap[e]-flow[e]));
            if (_d>0)
            {
                flow[e]+=_d;
                flow[e^1]-=_d;
                return _d;
            }
        }
    }

    return 0;
}

int max_flow(int s,int t)
{
    memset(flow,0,sizeof flow);
    int total_flow=0;

    for (;;)
    {
        dinic_bfs(s);

        if (lv[t]<0)    return  total_flow;

        memcpy(iter,fir,sizeof iter);

        int _f;
        while ((_f=dinic_dfs(s,t,INF)>0))
            total_flow+=_f;
    }

    return total_flow;
}

bool vis[maxn];

void dfs(int _u)
{
    vis[_u]=true;
    for (int e=fir[_u];~e;e=nex[e])
    {
        if (cap[e]>flow[e] && !vis[v[e]])
            dfs(v[e]);
    }
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("/home/fcbruce/文档/code/t","r",stdin);
    #endif // ONLINE_JUDGE

    int r,c,n,_u,_v;

    while (scanf("%d %d %d",&r,&c,&n),r||c||n)
    {
        int s=0,t=r+c+1;
        e_max=0;
        memset(fir,-1,sizeof fir);
        for (int i=1;i<=r;i++)
            add_edge(s,i,1);
        for (int i=r+1;i<=r+c;i++)
            add_edge(i,t,1);

        for (itn i=0;i<n;i++)
        {
            scanf("%d %d",&_u,&_v);
            add_edge(_u,_v+r,1);
        }

        printf("%d",max_flow(s,t));

        memset(vis,0,sizeof vis);
        dfs(s);

        for (int i=1;i<=r;i++)
            if (!vis[i])    printf(" r%d",i);

        for (int i=r+1;i<=r+c;i++)
            if (vis[i])    printf(" c%d",i-r);

        puts("");
    }

    return 0;
}

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

时间: 2024-10-08 09:30:20

UVA 11419 SAM I AM (二分图,最小割)的相关文章

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 (最小覆盖 K&#246;nig定理)

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

[二分图&amp;最小割]

[email protected] 反转源汇的模型: 给定一个二分图,同时选择集合中的两个点会有一个代价,选择每一个点有一个收益,问最大收益是多少 (即两个点在不同的集合中是有冲突关系的) 解法: 用最小割模型解决,通过反转源汇来表示冲突关系,用源S汇T表示选或不选,左边的黑点向S连黑点选择的收益(如果这条边割掉了就代表没有选择这个黑点,要减掉这个代价),向T连黑点不选择的收益(可以没有).右边的白点向S连白点不选择的收益,向T连白点选择的收益(此时把S,T和上述反转了一下).那么原图中两个点共

UVA 11248 Frequency Hopping (最大流+最小割)

题意:与正常的网络流一样,不过给定的第一行的最后一个数C的意思是能能否在给定的图里求出修改某一条边或者不修改某一条边是的这个图的流变成C,如果没修改就能有C,那么输出possible,通过修改能得到C输出possible+能修改的边集合,否则输出no possible 思路:(自己的是死暴力方法,直接爆了,想了很多法子都来不起,最后参照白书的思路来起了)可以先求出最大流,然后求出最小割里的弧,依次修改最小割里的弧,看能求出的最大流是否大于C PS:不优化的话很容易超时,第一个优化是把第一次求得得

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

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

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

bzoj 3158 千钧一发(最小割)

3158: 千钧一发 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 767  Solved: 290[Submit][Status][Discuss] Description Input 第一行一个正整数N. 第二行共包括N个正整数,第 个正整数表示Ai. 第三行共包括N个正整数,第 个正整数表示Bi. Output 共一行,包括一个正整数,表示在合法的选择条件下,可以获得的能量值总和的最大值. Sample Input 4 3 4 5 12 9

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

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

【Codevs1922】骑士共存问题(最小割,二分图最大匹配)

题意: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入. 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击. n<=200,m<=n^2 思路:经典的二分图最大匹配问题,采用黑白点染色的思想. 如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可. 这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想. 1