2018.11.06【HNOI2010】【洛谷P3209】【BZOJ1997】平面图判定Planar(二分图染色)(结论题)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/83792205

BZOJ传送门

洛谷传送门


解析:

首先记住一个结论:对于任意平面图都有 E 3 V 6 |E|\leq3|V|-6

证明一下:只考虑极大平面图(即点数一定时,边数达到最大的平面图)。其他的情况边数都小于同顶点数的极大平面图。

首先,极大平面图的每个平面由3条边围成,不然总是能够在这个形状中继续连一条对角线加边。

r r 为该平面图面数, m m 为边数, n n 为点数。
由于是极大平面图,所以有 3 r = 2 m 3r=2m ,即每条边被两个平面共享,每个平面由三条边围成。

由平面图的欧拉公式 n m + r = 2 n-m+r=2 (直接将拓扑学的立体图形映射到平面上即可得到),那么极大平面图有 m = 3 n 6 m=3n-6 。其他情况 m < m = 3 n 6 m'<m=3n-6

所以对于任意平面图,总是有 m 3 n 6 m\le 3n-6

那么我们就排除那些不符合题意的图,将边的规模优化到 O ( n ) O(n) 了。

由于这道题的图都有哈密尔顿回路,所以可以乱搞一下。

将哈密尔顿回路看作一个圈,剩下的边要么是圆上的弦,要么就在圆外。

显然如果两条边有交点,它们必须处于不同的两侧,

所以我们可以将它们连边,随后染色判断一下是否是二分图就行了。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline int getint(){
	re int num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
}

cs int N=205,M=10004;
vector<int> edge[N*3+8];
int a[M],b[M];
int H[N];

inline void addedge(int u,int v){
	edge[u].push_back(v);
	edge[v].push_back(u); 
}

int col[N*3+8];
int T,n,m;

inline void clear(){
	memset(col,-1,sizeof col);
	for(int re i=1;i<=m;++i)edge[i].clear();
}

inline bool dye(int u){
	for(int re e=0;e<edge[u].size();++e){
		int re v=edge[u][e];
		if(col[v]==col[u])return false;
		if(col[v]==-1){
			col[v]=col[u]^1;
			if(!dye(v))return false;
		}
	}
	return true;
}

signed main(){
	T=getint();
	while(T--){
		n=getint();
		m=getint();
		for(int re i=1;i<=m;++i){
			a[i]=getint();
			b[i]=getint();
		}
		for(int re i=1;i<=n;++i)H[getint()]=i;
		if(m>3*n-6){
			puts("NO");
			continue;
		}
		clear();
		for(int re i=1;i<=m;++i)
		for(int re j=i+1;j<=m;++j){
			int u1=H[a[i]],v1=H[b[i]],u2=H[a[j]],v2=H[b[j]];
			if(u1>v1)swap(u1,v1);
			if(u2>v2)swap(u2,v2);
			if((u1<u2&&u2<v1&&v1<v2)||(u2<u1&&u1<v2&&v2<v1)){
				addedge(i,j);
			}
		}
		bool flag=true;
		for(int re i=1;i<=m;++i){
			if(~col[i])continue;
			col[i]=0;
			if(!dye(i)){
				flag=false;
				break;
			}
		}
		puts(flag?"YES":"NO");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/83792205
今日推荐