BZOJ 3175 Tjoi2013 攻击装置 二分图最大匹配

来源:互联网 发布:初中网络课程 编辑:程序博客网 时间:2024/04/29 07:35

题目大意:给定一个n*n的网格图,要在0的位置上放置一些攻击装置,其中一个攻击装置的攻击范围是周围8个“日”字形区域,要求不能互相攻击,求最多放置多少个攻击装置

每两个能互相攻击且能放置的点连一条双向边,然后跑二分图最大点独立集即可

4W个点n^2居然没TLE 是数据太弱还是匈牙利算法太强了?

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 210using namespace std;struct abcd{int to,next;}table[M*M<<3];int head[M*M],tot;int n,m,ans;int map[M][M];int state[M*M],result[M*M],T;const int dx[]={1,1,2,2};const int dy[]={2,-2,1,-1};void Add(int x,int y){table[++tot].to=y;table[tot].next=head[x];head[x]=tot;}bool Hungary(int x){int i;for(i=head[x];i;i=table[i].next){if(state[table[i].to]==T)continue;state[table[i].to]=T;if( !result[table[i].to] || Hungary(result[table[i].to]) ){result[table[i].to]=x;return true;}}return false;}int main(){int i,j,k;cin>>n;for(i=1;i<=n;i++)for(j=1;j<=n;j++){scanf("%1d",&map[i][j]);if(map[i][j]==1)map[i][j]=-1;elsemap[i][j]=++m;}for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(~map[i][j])for(k=0;k<4;k++){int xx=i+dx[k];int yy=j+dy[k];if(xx<=0||yy<=0||xx>n||yy>n)continue;if(map[xx][yy]==-1)continue;Add(map[i][j],map[xx][yy]);Add(map[xx][yy],map[i][j]);}ans=m<<1;for(i=1;i<=m;i++){++T;if( Hungary(i) )--ans;}cout<<(ans>>1)<<endl;}


0 0
原创粉丝点击