【二分匹配】 UVALive 6525 Attacking rooks
横坐标 纵坐标 标好编号
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #define cler(arr, val) memset(arr, val, sizeof(arr)) #define FOR(i,a,b) for(int i=a;i<=b;i++) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 10052; const int MAXM = 6000010; const int INF = 0x3f3f3f3f; const int mod = 1e9; const double eps= 1e-8; #define lson l,m, rt<<1 #define rson m+1,r,rt<<1|1 int mp1[155][155],mp2[155][155]; char s[151][151]; const int N=31500; int use[N]; int linkx[N]; int linky[N]; struct node { int to,next; }edge[MAXN]; int head[N],tol; void addedge(int u,int v) { edge[tol].to=v,edge[tol].next=head[u]; head[u]=tol++; } int gn,gm; int can(int t) { int j; for(j=head[t];~j;j=edge[j].next) { int v=edge[j].to; if(use[v]==0) { use[v]=1;//标记 if(linky[v]==0 || can(linky[v])) { linky[v]=t; linkx[t]=v; return 1; } } } return 0; } int MaxMatch() { int i,num; num=0; memset(linkx,0,sizeof(linkx)); memset(linky,0,sizeof(linky)); for(i=1;i<gn;i++) { memset(use,0,sizeof(use)); if(can(i)) num++; } return num; } int main() { int n; #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif while(cin>>n) { memset(mp1,0,sizeof(mp1)); memset(mp2,0,sizeof(mp2)); tol=0; memset(head,-1,sizeof(head)); for(int i=0;i<n;i++) scanf("%s",s[i]); gn=1; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(s[i][j]=='.') mp1[i][j]=gn; else if(s[i][j]=='X') gn++; gn++; } gm=1; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(s[j][i]=='.') mp2[j][i]=gm; else if(s[j][i]=='X') gm++; gm++; } for(int i=0;i<n;i++) for(int j=0;j<n;j++) addedge(mp1[i][j],mp2[i][j]); printf("%d\n",MaxMatch()); } return 0; }