zoukankan      html  css  js  c++  java
  • [TJOI2013]攻击装置

    题目

    癌我竟然会做

    发现我们要求的是一个最大独立集问题

    发现一个格子和能攻击到的格子的奇偶性和它都不同,于是我们就可以按照(i+j)的奇偶性把整张图分成两个部分

    两个部分之间没有连边

    于是二分图最大独立集=总点数-最小点覆盖

    最小点覆盖=最大匹配

    代码

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define LL long long
    #define re register
    #define maxn 50005
    #define inf 99999999
    const int dx[]={-1,-2,1,2,-1,-2,1,2};
    const int dy[]={-2,-1,-2,-1,2,1,2,1};
    inline int read() {
    	int x=0;char c=getchar();while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    int n,num=1,S,T;
    struct E{int v,nxt,f;}e[maxn*12];
    int head[maxn],cur[maxn],d[maxn],id[205][205];
    char map[205][205];
    inline void add(int x,int y,int f) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;e[num].f=f;}
    inline void C(int x,int y,int f) {add(x,y,f),add(y,x,0);}
    inline int BFS() {
    	std::queue<int> q;
    	for(re int i=S;i<=T;i++) d[i]=0,cur[i]=head[i];
    	d[S]=1,q.push(S);
    	while(!q.empty()) {
    		int k=q.front();q.pop();
    		for(re int i=head[k];i;i=e[i].nxt)
    		if(e[i].f&&!d[e[i].v]) d[e[i].v]=d[k]+1,q.push(e[i].v);
    	}
    	return d[T];
    }
    int dfs(int x,int now) {
    	if(x==T||!now) return now;
    	int flow=0,ff;
    	for(re int& i=cur[x];i;i=e[i].nxt) 
    	if(d[e[i].v]==d[x]+1) {
    		ff=dfs(e[i].v,min(e[i].f,now));
    		if(ff<=0) continue;
    		now-=ff,flow+=ff,e[i].f-=ff,e[i^1].f+=ff;
    		if(!now) break;
    	}
    	return flow;
    }
    int main() {
    	n=read();
    	for(re int i=1;i<=n;i++) scanf("%s",map[i]+1);
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=n;j++)
    			if(map[i][j]=='0') id[i][j]=++T;
    	for(re int i=1;i<=n;i++)
    		for(re int j=1;j<=n;j++) {
    			if(!id[i][j]||((i+j)&1)) continue;
    			for(re int k=0;k<8;k++) {
    				int xx=i+dx[k],yy=j+dy[k];
    				if(xx<=1&&yy<=1&&xx>n||yy>n||!id[xx][yy]) continue;
    				C(id[i][j],id[xx][yy],1);
    			}
    		}
    	++T;
    	for(re int i=1;i<=n;i++) 
    		for(re int j=1;j<=n;j++) {
    			if(!id[i][j]) continue;
    			if((i+j)&1) C(id[i][j],T,1);
    				else C(S,id[i][j],1);
    		}
    	int ans=0;
    	while(BFS()) ans+=dfs(S,inf);
    	printf("%d
    ",T-1-ans);
    	return 0;
    }
    
  • 相关阅读:
    Service Name Port Number Transport Protocol tcp udp 端口号16bit
    linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
    soft deletion Google SRE 保障数据完整性的手段
    Taylor series
    Taylor's theorem
    Moving average
    REQUEST
    Unix file types
    mysqld.sock
    Tunneling protocol
  • 原文地址:https://www.cnblogs.com/asuldb/p/10489172.html
Copyright © 2011-2022 走看看