【题解】Bichromization(构造)

【题解】Bichromization(构造)

咕咕咕

删边操作直接令其=1e9就好了,图的构造肯定先想想直接构造成树怎么做,我们直接令需要满足\(D_i\)的条件的那些最短路就=一条边。那么直接弄出一颗WB相间的森林即可,并且令父边=\(D_i\)

但是每棵树的根节点没有父边啊!仔细思考发现,找到一个连接两个相等的\(D\)的并令其中一个为根即可。这样一条父边满足了两个\(D_i\)的条件的限制。

充分性是显然的,下证必要性

能够如上构造方案的充要条件是存在一条两端D相等的边。

这其实是两个条件,点和边。

先证最小的那条需要满足条件的路径的两端的D相同,不然一定有一个无法满足D的条件。设这条路径长度为len。

再证这条路径经过的点数=2,这也是显然的,因为如果>2,中间的一个点是无法满足条件的,因为这条路径两端是一W一B,一定有一个使得他的最短路<len,那么他永远无法满足条件。

具体实现直接bfs就好了。

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;  typedef long long ll;
inline int qr(){
	int ret=0,f=0,c=getchar();
	while(!isdigit(c)) f|=c==45,c=getchar();
	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
	return f?-ret:ret;
}
const int maxn=1e5+5;
const int inf=1e9;
struct E{
	int to,nx;
}e[maxn<<2];
int head[maxn],ans[maxn<<1],usd[maxn],n,m,cnt,D[maxn];
char col[maxn];
void add(int fr, int to){
	static int cnt=1;
	e[++cnt]=(E){to,head[fr]}; head[fr]=cnt;
	e[++cnt]=(E){fr,head[to]}; head[to]=cnt;
}
queue< int > q;

int main(){
	n=qr(); m=qr();
	for(int t=1;t<=n;++t)D[t]=qr();
	for(int t=1,a,b;t<=m;++t){
		a=qr(),b=qr(),add(a,b);
		if(D[a]==D[b]&&!col[a]&&!col[b]) q.push(a),q.push(b),col[a]='W',col[b]='B',ans[t]=D[a];
	}
	while(q.size()){
		int now=q.front(); q.pop();
		for(int t=head[now];t;t=e[t].nx)
			if(!col[e[t].to]&&D[e[t].to]>=D[now])
				col[e[t].to]="WB"[col[now]=='W'],ans[t>>1]=D[e[t].to],q.push(e[t].to);
	}
	for(int t=1;t<=n;++t)
		if(col[t]==0)
			return puts("-1"),0;
	puts(col+1);
	for(int t=1;t<=m;++t)
		printf("%d\n",ans[t]?ans[t]:inf);
	return 0;
}

posted @ 2020-03-09 21:30  谁是鸽王  阅读(204)  评论(0编辑  收藏  举报