LA 6187 - Never Wait for Weights 并查集的带权路径压缩

只有一个地方需要注意:

设节点a的根为u,b的跟为v,则:a = u + d[a];  b = v + d[b];

已知:b-a=w。所以v - u = d[a] - d[b] + w;

在合并两个集合修改根节点时,把v的根改为u,同时v到根的距离为d[a] - d[b] + w;

 #include <cstdio>
#include <cstring> const int MAXN = ; int pa[MAXN];
long long int d[MAXN]; int findset( int x )
{
if ( pa[x] == x ) return x;
int root = findset( pa[x] );
d[x] += d[ pa[x] ];
return pa[x] = root;
} int main()
{
int N, M;
while ( scanf( "%d%d", &N, &M ), N || M )
{
for ( int i = ; i <= N; ++i )
{
pa[i] = i;
d[i] = ;
}
while ( M-- )
{
char op[];
scanf( "%s", op );
int a, b, w;
if ( op[] == '!' )
{
scanf( "%d%d%d", &a, &b, &w );
int u = findset(a);
int v = findset(b);
pa[v] = u;
d[v] = d[a] - d[b] + w;
}
else
{
scanf( "%d%d", &a, &b );
int u = findset(a);
int v = findset(b);
if ( u != v ) puts("UNKNOWN");
else printf( "%lld\n", d[b] - d[a] );
}
}
}
return ;
}
上一篇:国内首款 FPGA 云服务器,性能是通用 CPU 服务器 30 倍以上


下一篇:springboot~Profile开发环境与单元测试用不同的数据库