AT5751 Bichromization

Link
注意到一定存在一个最短路森林,因此只能用森林来满足限制,剩下的边都设成\(+\infty\)
对于一条边\((u,v)\),如果\(d_u=d_v\),并且有一个点尚未被染色,那么我们就让这两个点的颜色互不相同,并让这条边的边权等于\(d_u\)
否则不妨设\(d_u>d_v\),并让\(v\)\(u\)的父亲,并让\(u,v\)同色,边权设为\(d_u-d_v\)
不难发现如果最后所有的点都有颜色,那么这一定是一组合法的方案。
否则一定不存在合法的方案。

#include<cstdio>
#include<algorithm>
const int N=100007;
int read(){int x;scanf("%d",&x);return x;}
int d[N],p[N],e[N],f[N],id[N],w[N*2];
int main()
{
    int n=read(),m=read();
    for(int i=1;i<=n;++i) d[p[i]=i]=read();
    std::sort(p+1,p+n+1,[](int i,int j){return d[i]<d[j];});
    for(int i=1,u,v;i<=m;++i)
	if(d[u=read()]==d[v=read()])
	{
	    if(!f[u]&&!f[v]) f[u]=1;
	    if(!f[u]) f[u]=-f[v];
	    if(!f[v]) f[v]=-f[u];
	    if(f[u]==-f[v]) w[i]=d[u];
	}
	else
	{
	    if(d[u]<d[v]) std::swap(u,v);
	    e[u]=v,id[u]=i;
	}
    for(int i=1,x;i<=n;++i)
	if(!f[x=p[i]])
	{
	    if(!e[x]) return puts("-1"),0;
	    f[x]=f[e[x]],w[id[x]]=d[x]-d[e[x]];
	}
    for(int i=1;i<=n;++i) putchar(f[i]>0? 'B':'W');
    for(int i=1;i<=m;++i) printf("\n%d",w[i]? w[i]:1000000000);
}
posted @ 2020-03-10 20:27  Shiina_Mashiro  阅读(150)  评论(0编辑  收藏  举报