Description
Input
Output
Sample Input
Sample Output
题目大意:给你n*n的矩阵,里面有些位置有墙。要在空地方放上炮弹,导弹会攻击上下左右四个方向,导弹的攻击不能通过墙即碰到墙就停止了。问你最多能在里面放入多少个炮弹。
解题思路:由于有墙的阻隔,所以不能简单地将行列直接分为二部。所以考虑一行中,如果遇到墙,可以认为是已经换行了,让行数加一。同样,列也这样考虑。在我们呢这种意义下的行列有交汇的地方,连一条边。求最大匹配。
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; int vis[110][110], G[110][110], linker[110], used[110]; char Map[110][110]; bool dfs(int u,int _n){ for(int v = 1; v <= _n; v++){ if(G[u][v] && !used[v]){ used[v] = u; if(linker[v] == -1 || dfs(linker[v],_n)){ linker[v] = u; return true; } } } return false; } int hungary(int un,int vn){ int ret = 0; memset(linker,-1,sizeof(linker)); for(int i = 1; i <= un; i++){ memset(used,0,sizeof(used)); if(dfs(i,vn)) ret++; } return ret; } int main(){ int n; while(scanf("%d",&n)!=EOF&&n){ for(int i = 1; i <= n; i++){ getchar(); for(int j = 1; j <= n; j++){ scanf("%c",&Map[i][j]); } } memset(vis,0,sizeof(vis)); int vn = 0, flag; for(int i = 1; i <= n; i++){ flag = 1; for(int j = 1; j <= n; j++){ if(Map[i][j] == ‘X‘){ flag = 1; }else{ if(flag) { vn++; flag = 0; } vis[i][j] = vn; } } } memset(G,0,sizeof(G)); int un = 0; for(int j = 1; j <= n; j++){ flag = 1; for(int i = 1; i <= n; i++){ if(Map[i][j] == ‘X‘){ flag = 1; }else{ if(flag){ un++; flag = 0; } G[un][vis[i][j]] = 1; } } } int ans = hungary(un,vn); printf("%d\n",ans); } return 0; }
HDU 1045——Fire Net——————【最大匹配、构图、邻接矩阵做法】
原文:http://www.cnblogs.com/chengsheng/p/4955246.html