zoukankan      html  css  js  c++  java
  • 洛谷 [P3355] 骑士共存问题

    二分图求最大独立点集

    本问题在二分图中已处理过,此处用dinic写了一遍

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int MAXN=40005,MAXM=5000005;
    int s,t,head[MAXN],nume,ma[205][205],dx[8]={-1,-2,-2,-1,1,2,2,1},dy[8]={2,1,-1,-2,2,1,-1,-2},dep[MAXN],cur[MAXN],n,m,maxflow;
    struct edge{
    	int to,nxt,cap,flow;
    }e[MAXM];
    void adde(int from,int to,int cap){
    	e[++nume].to=to;
    	e[nume].nxt=head[from];
    	e[nume].cap=cap;
    	head[from]=nume;
    }
    queue<int>q;
    bool bfs(){
    	memset(dep,0,sizeof(dep));
    	q.push(s);dep[s]=1;
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=head[u];i;i=e[i].nxt){
    			int v=e[i].to;
    			if(!dep[v]&&e[i].flow<e[i].cap){
    				dep[v]=dep[u]+1;
    				q.push(v);
    			}
    		}
    	}
    	return dep[t];
    }
    int dfs(int u,int flow){
    	if(u==t) return flow;
    	int tot=0;
    	for(int &i=cur[u];i&&tot<flow;i=e[i].nxt){
    		int v=e[i].to;
    		if(dep[v]==dep[u]+1&&e[i].flow<e[i].cap){
    			if(int t=dfs(v,min(flow-tot,e[i].cap-e[i].flow))){
    				e[i].flow+=t;
    				e[((i-1)^1)+1].flow-=t;
    				tot+=t;
    			}
    		}
    	}
    	return tot;
    }
    void dinic(){
    	while(bfs()){
    		for(int i=s;i<=t;i++) cur[i]=head[i];
    		maxflow+=dfs(s,0x3f3f3f3f);
    	}
    }
    int main(){
    	cin>>n>>m;
    	int cnt=0;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			ma[i][j]=++cnt;
    		}
    	}
    	for(int i=1;i<=m;i++){
    		int u,v;
    		cin>>u>>v;
    		ma[u][v]=0;
    	}	
    	s=0;t=cnt+1;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(ma[i][j]){
    				if((i+j)&1) adde(s,ma[i][j],1),adde(ma[i][j],s,0);
    				else adde(ma[i][j],t,1),adde(t,ma[i][j],0);
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(ma[i][j]&&((i+j)&1)){
    				for(int k=0;k<8;k++){
    					int x=i+dx[k],y=j+dy[k];
    					if(x>0&&x<=n&&y>0&&y<=n){
    						adde(ma[i][j],ma[x][y],1);
    						adde(ma[x][y],ma[i][j],0);
    					}
    				}
    			}
    		}
    	}
    	dinic();
    	cout<<cnt-maxflow-m<<endl;	
    	return 0;
    }
    
  • 相关阅读:
    Python动态展示遗传算法求解TSP旅行商问题
    MOEAD算法中均匀权向量的实现---Python
    HDU 5294 多校第一场1007题 最短路+最小割
    POJ 3261 Milk Patterns sa+二分
    HDU 4292 FOOD 2012 ACM/ICPC Asia Regional Chengdu Online
    CodeForces 201A Clear Symmetry
    POJ 1679 The Unique MST 确定MST是否唯一
    POJ 3268 Silver Cow Party 最短路 基础题
    POJ 2139 SIx Degrees of Cowvin Bacon 最短路 水題
    POJ2229 Sumsets 基礎DP
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8350501.html
Copyright © 2011-2022 走看看