题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6446
Problem Description There are N vertices connected by N−1 edges, each edge has its own length.
Input There are 10 test cases at most.
Output For each test case, print the answer module 109+7 in one line. Sample Input 3 1 2 1 2 3 1 3 1 2 1 1 3 2
Sample Output 16 24 |
题目大意:给出一个n,然后是n-1条路,对于每条路,输入,u->v 权值w;
最后给出全排列的1-n的所有长度之和,
样例:
这样的一颗树,然后输出,1-2-3,1-3-2,2-1-3,2-3-1,3-1-2,3-2-1,总共六种路径的长度之和;
分别为:
1->2->3=1->2+2->3=1+1=2
1->3->2 =1->2->3+2->3=2+1=3
2->1->3=2->1+1->2->3=1+2=3
.......
把他们都加起来即可;
因为是全排列,所以每两点之间出现的次数是相等的,例:
n=3时,有:
1,2,3 1,3,2
2,1,3 2,3,1
3,1,2 3,2,1
发现每两个点之间出现的次数时相等的,所以答案就是 点之间的重复次数 * 所有点到点之间的长度之和(1-2,1-3,2-3)
运用DFS树求出所有点到点之间的长度之和。
对于重复次数 ,可以打表找规律(大概打个10来项,然后找规律),也可以手推;
最后是F[i]=F[i-1]*(i-1);
然后输出答案即可
ac:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
//#define mod 1e9+7
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
const int MAXN=1e5+5;
const ll mod=1e9+7;
struct node{
int v,w;
ll nxt;
node(int _v=0,int _w=0,ll _nxt=0):
v(_v),w(_w),nxt(_nxt){}
}edge[MAXN<<1];
int head[MAXN],e;
ll sum,num[MAXN];
int n;
void intt()
{
clean(num,-1);
clean(head,-1);
e=0;
sum=0;
}
void add(int u,int v,ll w)
{
edge[e]=node(v,w,head[u]);
head[u]=e++;
}
void dfs(ll u,ll fa)
{
printf("%d %d\n",u,fa);
num[u]=1;
for(int i=head[u];i+1;i=edge[i].nxt)
{
int v=edge[i].v;
ll w=edge[i].w;
printf("%d %d\n%d %d %d\n",i,edge[i].nxt,u,v,fa);
if(v!=fa)//由于是无向图,因此我们要防止它向上回溯
{
dfs(v,u);
num[u]+=num[v];
sum=(sum+(num[v]*((n-num[v])*w)%mod)%mod)%mod;
}
}
}
ll ans[MAXN];
void init()
{
ans[2]=2;
ans[3]=4;
for(int i=4;i<MAXN;++i)
ans[i]=(ans[i-1]*(i-1))%mod;
}
int main()
{
init();
while(scanf("%d",&n)!=EOF)
{
intt();
int a,b;
ll l;
for(int i=0;i<n-1;++i)
{
scanf("%d%d%lld",&a,&b,&l);
add(a,b,l);
add(b,a,l);
}
dfs(1,-1);
printf("%lld\n",(sum*ans[n])%mod);
}
}