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);
}