【题解】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;
}

猜你喜欢

转载自www.cnblogs.com/winlere/p/12451717.html