zoukankan      html  css  js  c++  java
  • 网络瘤好题 洛谷 P5030 长脖子鹿放置

    题目链接

    其实这是一道匈牙利裸题。。。主要难点在于建二分图。

    这是题目给的图。。。

    这是某位神犇给的图。。。

    一目了然二分图怎么建。。。
    话不多说,直接上代码。。。

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    using namespace std;
    template<class T>
    inline void read(T& p) {
    	char c;
    	p=0;
    	bool f=0;
    	for(c=getchar(); c<'0'||c>'9'; c=getchar())if(c=='-')f=true;
    	for(; c>='0'&&c<='9'; c=getchar()) p=(p<<3)+(p<<1)+c-'0';
    	if(f)p=-p;
    }
    template<class T,class... Args>
    inline void read(T& x,Args&... args) {
    	read(x);
    	read(args...);
    }
    template<class T>
    inline void write(T x) {
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar('0'+x%10);
    }
    template<class T,class... Args>
    inline void write(T x,Args... args) {
    	write(x);
    	putchar(' ');
    	write(args...);
    }
    template<class... Args>
    inline void writeln(Args... args) {
    	write(args...);
    	putchar('
    ');
    }
    int n,m,e,ans;
    int u,v;
    vector<int> dis[40001];
    bool vis[40001];
    bool zi[201][201];
    int match[40001];
    int fx[8]= {-3,-3,-1,-1,1,1,3,3};
    int fy[8]= {-1,1,-3,3,-3,3,-1,1};
    inline int num(int x,int y) {
    	return (x-1)*n+y;
    }
    bool find(int x) {
    	for(register int i=0,to; i<dis[x].size(); i++) {
    		to=dis[x][i];
    		if(!vis[to]) {
    			vis[to]=true;
    			if(!match[to]||find(match[to])) {
    				match[to]=x;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    int max_match() {
    	int ans=0;
    	for(register int i=1; i<=n; i+=2) {
    		for(register int j=1; j<=m; j++) {
    			if(!zi[i][j]) {
    				memset(vis,0,sizeof(vis));
    				if(find(num(i,j)))ans++;
    			}
    		}
    	}
    	return ans;
    }
    int main() {
    	read(n,m,e);
    	for(register int i=1,x,y; i<=e; i++) {
    		read(x,y);
    		zi[x][y]=1;
    	}
    	for(register int i=1; i<=n; i+=2) {
    		for(register int j=1; j<=m; j++) {
    			if(zi[i][j])continue;
    			for(register int k=0; k<8; k++) {
    				int _x=i+fx[k],_y=j+fy[k];
    				if(_x<1||_y<1||_x>n||_y>m||zi[_x][_y])continue;
    				dis[num(i,j)].push_back(num(_x,_y));
    			}
    		}
    	}
    	write(n*m-e-max_match());
    	return 0;
    }
    

    蜜汁80分,emm被卡常了。。。
    不用STL,用链式前向星。。。

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    using namespace std;
    template<class T>
    inline void read(T& p) {
    	char c;
    	p=0;
    	bool f=0;
    	for(c=getchar(); c<'0'||c>'9'; c=getchar())if(c=='-')f=true;
    	for(; c>='0'&&c<='9'; c=getchar()) p=(p<<3)+(p<<1)+c-'0';
    	if(f)p=-p;
    }
    template<class T,class... Args>
    inline void read(T& x,Args&... args) {
    	read(x);
    	read(args...);
    }
    template<class T>
    inline void write(T x) {
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar('0'+x%10);
    }
    template<class T,class... Args>
    inline void write(T x,Args... args) {
    	write(x);
    	putchar(' ');
    	write(args...);
    }
    template<class... Args>
    inline void writeln(Args... args) {
    	write(args...);
    	putchar('
    ');
    }
    struct edge {
    	int u,v,next;
    } a[2000001];
    int n,m,e,ans;
    int u,v;
    int tot,fr[40001];
    bool vis[40001];
    bool zi[201][201];
    int match[40001];
    int fx[8]= {-3,-3,-1,-1,1,1,3,3};
    int fy[8]= {-1,1,-3,3,-3,3,-1,1};
    inline int num(int x,int y) {
    	return (x-1)*n+y;
    }
    inline void add(int from,int to) {
    	a[++tot].u=from;
    	a[tot].v=to;
    	a[tot].next=fr[from];
    	fr[from]=tot;
    }
    bool find(int x) {
    	for(register int now=fr[x],to;now;now=a[now].next) {
    		to=a[now].v;
    		if(!vis[to]) {
    			vis[to]=true;
    			if(!match[to]||find(match[to])) {
    				match[to]=x;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    int max_match() {
    	int ans=0;
    	for(register int i=1; i<=n; i+=2) {
    		for(register int j=1; j<=m; j++) {
    			if(!zi[i][j]) {
    				memset(vis,0,sizeof(vis));
    				if(find(num(i,j)))ans++;
    			}
    		}
    	}
    	return ans;
    }
    int main() {
    	read(n,m,e);
    	for(register int i=1,x,y; i<=e; i++) {
    		read(x,y);
    		zi[x][y]=1;
    	}
    	for(register int i=1; i<=n; i+=2) {
    		for(register int j=1; j<=m; j++) {
    			if(zi[i][j])continue;
    			for(register int k=0; k<8; k++) {
    				int _x=i+fx[k],_y=j+fy[k];
    				if(_x<1||_y<1||_x>n||_y>m||zi[_x][_y])continue;
    				add(num(i,j),num(_x,_y));
    			}
    		}
    	}
    	write(n*m-e-max_match());
    	return 0;
    }
    

    好了AC了

  • 相关阅读:
    将参数传递给线程(Vc#2005)
    ADO.NET更新ACCESS碰到的怪异问题
    MVCRESTSilverLight 之 MapServiceRoute
    MEF Export 和 Import 委托
    MVCRESTSilverLight 之MainPage.xaml.cs
    设计模式访问者
    MVCRESTSilverLight 之 ViewModels\MainViewModel.cs
    MVCRESTSilverLight 之Api\CustomerApi.cs
    MVCRESTSilverLight 之 RestExample.Model.Silverlight\Customer.cs
    MVCRESTSilverLight 之 HttpConfiguration
  • 原文地址:https://www.cnblogs.com/STOGMH/p/11519849.html
Copyright © 2011-2022 走看看