Abandoned country
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2586 Accepted Submission(s): 643
For each test case, the first line contains two integers n,m indicate the number of villages and the number of roads to be re-built. Next m lines, each line have three number i,j,wi, the length of a road connecting the village i and the village j is wi.
給定一張圖,求最小生成樹,並求在圖中任取兩點,兩點間路徑代價的期望值。
也就是求最小生成樹中:邊權*左子樹的大小*右子樹的大小的和再除以n*(n-1);
先求最小生成樹,並在尋找樹的過程中,保留最小生成樹上的邊,用於後續計算期望。採用dfs的方式,任意從樹上一點出發,計算該節點所在的子樹上的節點數x,並由總數減去x得到邊另一側的節點數。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef __int64 ll;
struct node
{
ll st,en,len;
}E[1000005];
struct Edge
{
ll en,next,len;
}edge[1000005];
ll num,head[100005],fa[100005],n,m,expect;
void init()
{
num=0;expect=0;
memset(head,-1,sizeof(head));
memset(E,0,sizeof(E));
memset(edge,0,sizeof(edge));
}
void add(ll st,ll en,ll len)
{
edge[num].en=en;
edge[num].len=len;
edge[num].next=head[st];
head[st]=num++;
}
bool cmp(node &a,node &b)
{
return a.len<b.len;
}
ll find(ll x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
ll kruskal()
{
ll cnt=0,ans=0;
for(ll i=0;i<=n;i++)
fa[i]=i;
for(ll i=0;i<m;i++)
{
ll fx=find(E[i].st);
ll fy=find(E[i].en);
if(fx!=fy)
{
ans+=E[i].len;
fa[fx]=fy;
cnt++;
add(E[i].st,E[i].en,E[i].len);
add(E[i].en,E[i].st,E[i].len);
if(cnt==n-1) break;
}
}
return ans;
}
ll dfs(ll x,ll fa)
{
ll tmp,res=1;
for(ll i=head[x];i!=-1;i=edge[i].next)
{
if(edge[i].en!=fa)
{
tmp=dfs(edge[i].en,x);
expect+=1.0*(n-tmp)*tmp*edge[i].len;
res+=tmp;
}
}
return res;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%I64d%I64d",&n,&m);
for(ll i=0;i<m;i++)
{
scanf("%I64d%I64d%I64d",&E[i].st,&E[i].en,&E[i].len);
}
sort(E,E+m,cmp);
ll ans=kruskal();
dfs(1,-1);
double ans1=2.0*expect/((n-1)*n);
printf("%I64d %.2lf\n",ans,ans1);
}
return 0;
}