题目大意:给定一个n*n的网格图,要在0的位置上放置一些攻击装置,其中一个攻击装置的攻击范围是周围8个“日”字形区域,要求不能互相攻击,求最多放置多少个攻击装置
每两个能互相攻击且能放置的点连一条双向边,然后跑二分图最大点独立集即可
4W个点n^2居然没TLE 是数据太弱还是匈牙利算法太强了?
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 210 using 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; else map[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; }
时间: 2024-11-09 23:24:38