标签:style blog class code ext int
将行中连续的‘ . ‘当作X集的一个点,列中连续的’ . ‘看成Y集中的一个点,然后把每一个’ . ‘看成一条边,连接Xi,Yj。
则问题转化成求此二分的最大匹配数。每找到一条匹配边的意义是找到了一个点放置一个,并且覆盖了所在的连续的行和列。
所以答案即为此二分图的最大匹配。
20s的时限,只跑了29ms。。。。这是有多不相信自己的服务器。。。。
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long LL #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 1000000007 #define LM(a,b) (((ULL)(a))<<(b)) #define RM(a,b) (((ULL)(a))>>(b)) using namespace std; const LL MAXN = 100001; struct N { int v,next; }edge[MAXN*2]; int head[MAXN]; int Top; void Link(int u,int v) { edge[Top].v = v; edge[Top].next = head[u]; head[u] = Top++; } void Init_head_Top(int n) { memset(head,-1,sizeof(int)*(n+2)); Top = 0; } int Match_Point[MAXN]; bool mark[MAXN]; bool dfs(int s) { for(int p = head[s] ; p != -1; p = edge[p].next) { if(mark[edge[p].v] == false) { mark[edge[p].v] = true; if(Match_Point[edge[p].v] == -1 || dfs(Match_Point[edge[p].v])) { Match_Point[s] = edge[p].v; Match_Point[edge[p].v] = s; return true; } } } return false; } int Cal_Max_Match(int n) { int ans = 0; for(int i = 1;i <= n; ++i) { if(Match_Point[i] == -1) { memset(mark,false,sizeof(bool)*(n+2)); if(dfs(i)) ans++; } } return ans; } char Map[110][110]; int ansx[110][110]; int ansy[110][110]; int main() { int n; int i,j; while(scanf("%d",&n) != EOF) { for(i = 1;i <= n; ++i) { scanf("%s",Map[i]+1); } memset(ansx,-1,sizeof(ansx)); memset(ansy,-1,sizeof(ansy)); memset(Match_Point,-1,sizeof(int)*(n*n*2+2)); int ty = 0; for(i = 1;i <= n; ++i) { for(j = 1;j <= n; ++j) { if(Map[i][j] == ‘.‘) { ansx[i][j] = (ansx[i][j-1] == -1 ? ++ty : ansx[i][j-1]); } } } Init_head_Top(n*n*2); int ans = 0; for(j = 1;j <= n; ++j) { for(i = 1;i <= n; ++i) { if(Map[i][j] == ‘.‘) { ansy[i][j] = (ansy[i-1][j] == -1 ? ++ty : ansy[i-1][j]); Link(ansx[i][j],ansy[i][j]); Link(ansy[i][j],ansx[i][j]); if(Match_Point[ansx[i][j]] == -1 && Match_Point[ansy[i][j]] == -1) { Match_Point[ansx[i][j]] = ansy[i][j],Match_Point[ansy[i][j]] = ansx[i][j],ans++; } } } } printf("%d\n",ans+Cal_Max_Match(ty)); } return 0; }
UVALive 6525 Attacking rooks,布布扣,bubuko.com
标签:style blog class code ext int
原文地址:http://blog.csdn.net/zmx354/article/details/25202179