网络瘤好题 洛谷 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('\n');
}
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('\n');
}
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了

posted @ 2019-09-14 18:55  G_M_H  阅读(205)  评论(1编辑  收藏  举报