zoukankan      html  css  js  c++  java
  • UVA 11419 SAM I AM

    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 the temple 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.

    题目大意:
    大小为R*C的网格图中存在一些点需要被打掉,每次可以选择打掉任意一行或任意一列,求最小的步数将所有的点都打掉,并输出方案

    解题报告:
    这题是一个简单的二分图最小点覆盖问题,显然如果每一条边对应一个网格图中的一个点的话,那么答案就是用最小的点去覆盖所有的边
    考虑输出方案:
    设左右两图分别为X,Y 我们选择X中未匹配的点去遍历他的出边,显然这样做答案就是X集合中未标记的点,Y集合中标记了的点,至于为什么Y中标记的点就是答案:因为假设X集合中a未被匹配,那么它所对应的出边就没有被覆盖,所以它的另外一边必然存在于最大匹配中

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=2005,M=1000005;
    int head[N],to[M<<1],nxt[M<<1],n,m,k,bel[N],num=0;bool vis[N],v[N];
    void link(int x,int y){
    	nxt[++num]=head[x];to[num]=y;head[x]=num;
    }
    int gi(){
    	int str=0;char ch=getchar();
    	while(ch>'9' || ch<'0')ch=getchar();
    	while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
    	return str;
    }
    bool dfs(int x){
    	int u;v[x]=true;
    	for(int i=head[x];i;i=nxt[i]){
    		u=to[i];if(vis[u])continue;
    		vis[u]=true;
    		if(!bel[u] || dfs(bel[u])){
    			bel[u]=x;bel[x]=u;
    			return true;
    		}
    	}
    	return false;
    }
    void Clear(){
    	memset(head,0,sizeof(head));num=0;
    	memset(bel,0,sizeof(bel));
    }
    void work()
    {
    	Clear();
    	int x,y;
    	for(int i=1;i<=k;i++){
    		x=gi();y=gi();
    		link(x,y+n);link(y+n,x);
    	}
    	int ans=0;
    	for(int i=1;i<=n+m;i++){
    		if(!bel[i]){
    			memset(vis,0,sizeof(vis));
    			ans+=dfs(i);
    		}
    	}
    	printf("%d",ans);
    	memset(vis,0,sizeof(vis));
    	memset(v,0,sizeof(v));
    	for(int i=1;i<=n;i++)
    		if(!bel[i])dfs(i);
    	for(int i=1;i<=n;i++)
    		if(!v[i])printf(" r%d",i);
    	for(int i=1;i<=n;i++){
    		if(vis[i+n])printf(" c%d",i);
    	}
    	puts("");
    }
    
    int main()
    {
    	while(~scanf("%d%d%d",&n,&m,&k)){
    		if(n+m+k==0)break;
    		work();
    	}
    	return 0;
    }
    
  • 相关阅读:
    爬虫必看,每日JS逆向之爱奇艺密码加密,今天你练了吗?
    每日JS逆向练习之斗鱼登录密码加密,今天你练了吗?
    兄弟们,我打算抠100个网站JS加密代码召唤,一个也跑不掉,这次轮到小虎牙
    这个爬虫JS逆向加密任务,你还不来试试?逆向入门级,适合一定爬虫基础的人
    兄弟,你爬虫基础这么好,需要研究js逆向了,一起吧(有完整JS代码)
    四十一:快速排序(递归)
    第四十次发博不知道用什么标题好
    第三十九次发博不知道发什么好
    第三十八次发博不知道用什么标题好
    第三十七次发博不知道用什么标题好
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7489717.html
Copyright © 2011-2022 走看看