标签:space details 例题 int color end ref lse hdu
博文:https://blog.csdn.net/yjr3426619/article/details/82315133
带全并查集
路径压缩,表达每个当前node与 当前node所在的并查集的root 之间的关系
并查集一定是单向连通的,所以一些node处理时 【node1,node2】 weight 可能需要把 一端的闭区间变为开区间
俩个相对信息求出绝对信息 --水题
例题 : HDU 3038
//带权值并查集 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 2e5 + 25; int dis[maxn]; int p[maxn]; int find(int u)//寻根 { if(u!=p[u]) { int tmp = p[u];//保存原来的根节点 p[u] = find(p[u]);//路径压缩 dis[u] += dis[tmp];//dis[tmp] 已经为tmp(即原来父节点)到根节点的距离所以加上本身自身到tmp的dis则为u到root的dis } return p[u]; } void merge(int u,int v,int value) { int f1 = find(u); int f2 = find(v); p[f1] = f2; dis[f1] = value + dis[v] - dis[u]; }//带权并查集合并 int main() { int n,m;//n节点,m条边 while(cin>>n>>m) { int ans = 0,u,v,value; for(int i=0;i<=n;++i) { dis[i] = 0; p[i] = i; } while(m--) {//图改成了从0开始(important) cin>>u>>v>>value; --u; if(find(u)==find(v)) { if((dis[u]-dis[v])!=value) ++ans; }else{ merge(u,v,value);//否则合并 } } cout<<ans<<endl; } }
hihoCoder 1515
//带权并查集
#include<iostream>
#include<cstdio>//不是同一集合,合并,否则不做操作
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5 + 15;
int dis[maxn],p[maxn];//当前node到root的距离
int find(int u)
{
if(u!=p[u])
{
int tmp = p[u];
p[u] = find(p[u]);
dis[u] += dis[tmp];
}
return p[u];
}
int main()
{
int n,m,q;//n个节点,m条边,q个查询
while(cin>>n>>m>>q)
{
for(int v=1;v<=n;++v)
{
dis[v] = 0;
p[v] = v;
}
int u,v,value;
while(m--)
{
cin>>u>>v>>value;
int f1 = find(u);
int f2 = find(v);
if(f1!=f2)
{
p[f1] = f2;
dis[f1] = value + dis[v] - dis[u];
}
}
while(q--)
{
cin>>u>>v;
if(find(u)!=find(v))
cout<<-1<<endl;
else
cout<<dis[u] - dis[v]<<endl;
}
}
}
标签:space details 例题 int color end ref lse hdu
原文地址:https://www.cnblogs.com/newstartCY/p/11601164.html