首页 > 代码库 > nyoj237 游戏高手的烦恼(最小点覆盖)
nyoj237 游戏高手的烦恼(最小点覆盖)
游戏高手的烦恼
时间限制:1000 ms | 内存限制:65535 KB
难度:5
- 描写叙述
有一位传说级游戏高手。在闲暇时间里玩起了一个小游戏,游戏中,一个n*n的方块形区域里有很多敌人。玩家能够使用炸弹炸掉某一行或者某一列的全部敌人。
他是种玩什么游戏都想玩得非常优秀的人。所以。他决定。使用尽可能少的炸弹炸掉全部的敌人。
如今给你一个游戏的状态,请你帮助他推断最少须要多少个炸弹才干炸掉全部的敌人吧。
比方说,下图中X表示敌人
X . X
. X .. X .
则,他仅仅须要炸掉第1行与第2列就能炸掉全部的敌人,所以仅仅须要两颗炸弹就能够了。
- 输入
- 第一行是一个整数T,表示測试数据的组数(0<T<=400)。
每组測试数据的第一行有两个整数n,K,当中n表示游戏方形区域的大小。(n<=500,K<=10 000)
随后的K行。每行有两个整数i,j表示第i行,第j列有一个敌人(行和列都从1開始编号)。(1<=i,j<=n)
- 输出
- 对于每组測试数据,输出一个整数表示最少须要的炸弹颗数
- 例子输入
1 3 4 1 1 1 3 2 2 3 2
- 例子输出
2
- 来源
- POJ翻译而来
- 上传者
- 张云聪
题意就是用最少的炸弹 消灭全部敌人 也就是最小点覆盖。
而最小点覆盖能够通过最大匹配实现。
要想求最大匹配 最好的算法就是匈牙利算法
而在这道题中 怎样构图又成了不easy理解的地方。我们能够这样想
因为炸弹能够炸一行或一列
假设第i行 第j列有一个敌人 能够想象成 i点和j点有关系。
问题就变成
pid=239">点击打开链接
#include <stdio.h> #include <vector> #include <string.h> using namespace std; vector<int>map[505]; bool vis[505]; int conn[505]; bool dfs(int x) { for(int i=0;i<map[x].size();i++) { int y=map[x][i]; if(!vis[y]) { vis[y]=true; if(conn[y]==0||dfs(conn[y])) { conn[y]=x; return true; } } } return false; } int main() { int ncase; scanf("%d",&ncase); while(ncase--) { int n,k; memset(conn,0,sizeof(conn)); memset(map,0,sizeof(map)); scanf("%d %d",&n,&k); for(int i=0;i<k;i++) { int a,b; scanf("%d %d",&a,&b); map[a].push_back(b); } int ans=0; for(int i=1;i<=n;i++) { memset(vis,false,sizeof(vis)); if(dfs(i)) ans++; } printf("%d\n",ans); } return 0; }
nyoj237 游戏高手的烦恼(最小点覆盖)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。