首页 > 代码库 > LA 6525 Attacking rooks 二分匹配
LA 6525 Attacking rooks 二分匹配
题意:
给定n*n的棋盘,
可以在‘.‘上摆 象棋中的车(X是墙壁)
使得任意两个车都不能互相攻击到
求最多能摆多少个车。
思路:将每行中连续为.的作为X集合中一个点,同样,将每列中连续为.的点作为Y集合中的一个点。对原图中每个‘.‘,将其对应的X
集合和Y集合中的标号建边,便形成了二分图,对该图求最大匹配。详见代码:
/********************************************************* file name: LA6525.cpp author : kereo create time: 2015年01月31日 星期六 21时40分08秒 *********************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int sigma_size=26; const int N=100+50; const int MAXN=10000+50; const int inf=0x3fffffff; const double eps=1e-8; const int mod=100000000+7; #define L(x) (x<<1) #define R(x) (x<<1|1) #define PII pair<int, int> #define mk(x,y) make_pair((x),(y)) int n,edge_cnt; char mp[N][N]; int x[N][N],y[N][N],link[MAXN],vis[MAXN],head[MAXN]; struct Edge{ int v,next; }edge[MAXN]; void init(){ edge_cnt=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v){ edge[edge_cnt].v=v; edge[edge_cnt].next=head[u]; head[u]=edge_cnt++; } bool dfs(int u){ for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(vis[v]) continue; vis[v]=1; if(link[v] == -1 || dfs(link[v])){ link[v]=u; return true; } } return false; } int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ init(); for(int i=0;i<n;i++) scanf("%s",mp[i]); int cnt1=0,cnt2=0; for(int i=0;i<n;i++){ int flag=1; for(int j=0;j<n;){ if(j<n && mp[i][j] == '.'){ while(j<n && mp[i][j] == '.'){ if(flag){ ++cnt1; flag=0; } x[i][j]=cnt1; j++; } } else if(j<n && mp[i][j] == 'X'){ while(j<n && mp[i][j] == 'X'){ flag=1; j++; } } } } for(int j=0;j<n;j++){ int flag=1; for(int i=0;i<n;){ if(i<n && mp[i][j] == '.'){ while(i<n && mp[i][j] == '.'){ if(flag){ ++cnt2; flag=0; } y[i][j]=cnt2; i++; } } else if(i<n && mp[i][j] == 'X'){ while(i<n && mp[i][j] == 'X'){ flag=1; i++; } } } } int X=0,Y=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(mp[i][j] == '.' && (x[i][j]!=X || y[i][j]!=Y)){ addedge(x[i][j],y[i][j]); X=x[i][j],Y=y[i][j]; } memset(link,-1,sizeof(link)); int res=0; for(int i=1;i<=cnt1;i++){ memset(vis,0,sizeof(vis)); if(dfs(i)) res++; } printf("%d\n",res); } return 0; }
LA 6525 Attacking rooks 二分匹配
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。