标签:
有一位传说级游戏高手,在闲暇时间里玩起了一个小游戏,游戏中,一个n*n的方块形区域里有许多敌人,玩家可以使用炸弹炸掉某一行或者某一列的所有敌人。他是种玩什么游戏都想玩得很优秀的人,所以,他决定,使用尽可能少的炸弹炸掉所有的敌人。
现在给你一个游戏的状态,请你帮助他判断最少需要多少个炸弹才能炸掉所有的敌人吧。
比如说,下图中X表示敌人
X . X
. X .
. X .
则,他只需要炸掉第1行与第2列就能炸掉所有的敌人,所以只需要两颗炸弹就可以了。
题意就是用最少的炸弹 消灭所有敌人 也就是最小点覆盖。
而最小点覆盖可以通过最大匹配实现。
要想求最大匹配 最好的算法就是匈牙利算法
而在这道题中 如何构图又成了不容易理解的地方。我们可以这样想
由于炸弹可以炸一行或一列
如果第i行 第j列有一个敌人 可以想象成 i点和j点有关系。
问题就变成点击打开链接
#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; }
标签:
原文地址:http://blog.csdn.net/su20145104009/article/details/51106826