Spoj 3974 3974. Another Tree Problem 八中OJ

Spoj 3974 3974. Another Tree Problem

Time Limit:1000MS  Memory Limit:65536K
Total Submit:13 Accepted:2

Description

As you are bound to know by now, a tree is a connected graph
consisting of N vertices and N−1 edges. Trees also have the property
of there being exactly a single unique path between any pair of
vertices.
You will be given a tree in which every edge is assigned a weight –
a non negative integer. The weight of a path is the product of the
weights of all edges on the path. The weight of the tree is the sum of
the weights of all paths in the tree. Paths going in opposite
directions (A to B and B to A) are considered the same and, when
calculating the weight of a tree, are counted only once.
Write a program that, given a tree, calculates its weight modulo 1000000007.

Input

The first line contains the integer N (2 ≤ N ≤ 100 000), the number of vertices
in the tree. The vertices are numbered 1 to N. Each of the following N−1
contains three integers A, B and W (1 ≤ A, B ≤ N, 0 ≤ W ≤ 1000)
describing one edge. The edge connects vertices A and B, and its weight is W.

Output

Output the weight of the tree, modulo 1000000007.

Sample Input

3
3 2 100
2 1 100

Sample Output

10200

Hint

The weight of the path from 1 to 2 is 100
The weight of the path from 2 to 3 is 100
The weight of the path from 1 to 3 is 100 * 100 = 10000
So the weight of the tree is 10000 + 100 + 100 = 10200

Source
靠。。由于我毫无智商。。。这个题目很显然Dfs一下就可以解决了。。但我以前居然写个树的分治去做。。我真是脑缺啊囧。。。。
是在太鄙视自己了。。
Code:

#include <vector>
#include <algorithm>
#include <utility>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <set>
#include <map>
#include <cstring>
#include <time.h>
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define Debug(x) cout<<#x<<"="<<x<<endl;
#define For(i,l,r) for(int i=l;i<=r;i++)
#define tr(e,x) for(eit e=x.begin();e!=x.end();e++)
const int inf=~0U>>1,maxn=100000,mod=1000000007;
using namespace std;
typedef long long ll;
int n;
struct Edge
{
int t,c;
Edge(int _t,int _c):t(_t),c(_c){}
};
vector<Edge> E[maxn];
typedef vector<Edge>::iterator eit;
void InsEdge(int s,int t,int c)
{
E[s].pb(Edge(t,c));E[t].pb(Edge(s,c));
}
ll pow(int x,int e)
{
if(!e)return 1;
ll tmp=pow(x,e/2);tmp*=tmp;tmp%=mod;
if(e&1)tmp*=x,tmp%=mod;
return tmp;
}
ll Sum[maxn],P,ans=0;
int Q[maxn],F[maxn],h,t;
void BFS(int vs)
{
h=t=0;
for(Q[t++]=vs,F[vs]=-1;h<t;h++)
{
int x=Q[h];
tr(e,E[x])if(e->t!=F[x])
F[e->t]=x,Q[t++]=e->t;
}
for(int i=h-1;i>=0;i–)
{
int x=Q[i];Sum[x]=1;
ll all,tmp,ret=0;
tr(e,E[x])if(e->t!=F[x])
Sum[x]+=Sum[e->t]*e->c,Sum[x]%=mod;
all=Sum[x]+1;
tr(e,E[x])if(e->t!=F[x])
tmp=Sum[e->t]*e->c,tmp%=mod,ret+=(all-tmp)*tmp,ret%=mod;
ret*=P;ret%=mod;if(ret<0)ret+=mod;ans+=ret;ans%=mod;
}
}
int main()
{
//freopen("in","r",stdin);
cin>>n;int s,t,c;
rep(i,n-1)
{
scanf("%d%d%d",&s,&t,&c);–s;–t;
InsEdge(s,t,c);
}
P=pow(2,mod-2);
BFS(0);
cout<<ans<<endl;
}

Leave a Reply

Your email address will not be published. Required fields are marked *