正题
题目大意
nnn个点nnn条边的图,每条边的边权为两个连接节点的权值和,给出所有边权,求每个节点权值(保证唯一的环为奇环)
解题思路
首先并查集找到环上相邻的两个点,然后可以发现这两个点之间有两个关系(也就是两条路径)可以求出其中一个点的权值,然后推出其他点的权值即可
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+10;
struct node{ll to,next,w;
}a[N*2];
ll n,fa[N],w[N],ls[N],tot,p1,p2,val;
ll find(ll x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
void addl(ll x,ll y,ll w){a[++tot].to=y;a[tot].next=ls[x];a[tot].w=w;ls[x]=tot;
}
void dfs(ll x,ll fa,ll dis){if(x==p2){w[p1]=(val-dis)/2;return;}for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dfs(y,x,a[i].w-dis);}
}
void solve(ll x,ll fa){for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;w[y]=a[i].w-w[x];solve(y,x);}
}
int main()
{
int size = 256 << 20; //250M
char*p=(char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) );scanf("%lld",&n);for(ll i=1;i<=n;i++)fa[i]=i;for(ll i=1;i<=n;i++){ll x,y,Fa,Fb,w;scanf("%lld%lld%lld",&x,&y,&w);Fa=find(x);Fb=find(y);if(Fa<Fb)swap(Fa,Fb);if(Fa==Fb)p1=x,p2=y,val=w;else addl(x,y,w),addl(y,x,w),fa[Fa]=Fb;}dfs(p1,0,0);solve(p1,0);for(ll i=1;i<=n;i++)printf("%lld\n",w[i]);
}