root(v)指向一节点的边权=depth(v)+x;求生成树的总边长。
用并查集的方法,用fa[x]记录x的父节点,dist[x]表示x到当前根的长度。
PS:int weigh=((x+dist[v])%P+P)%P;//新边
//新边为啥要这样取摸才能过呢,折腾了半天,还不懂是什么原因啊,,有时间去请教大牛们,路过的求你帮偶解答一下。
#include <iostream>
#include <set>
#include <string>
#include <cstdio>
using namespace std;
const long long P=1000000007;
int fa[100002];
int dist[100002];
int n;
void initset()
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
dist[i]=0;
}
}
int findx(int v)
{
if (fa[v] == v)
return v;
int f =findx (fa[v]);
dist[v] = (dist[fa[v]] + dist[v]) % P;//递归回溯的时候记录它到当前根的长度
return fa[v] = f;
}
long long sum=0;
int main()
{
cin>>n;
initset();
for(int i=1;i<=n;i++)
{
int k;
cin>>k;
while(k--)
{
int v,x;
cin>>v>>x;
int newed=findx(v);
int weigh=((x+dist[v])%P+P)%P;//新边
sum=(sum+weigh)%P;
fa[newed]=i;
dist[newed]=weigh;
}
}
cout<<sum<<endl;
return 0;
}