列表

详情


NC14598. 标准差

描述

对于一张n个点m条边的有向图,边上有边权we,你需要找到一条1到n的路径使得经过的边的标准差最小。
x1,x2,...,xk的标准差计算方法如下:
 设
则标准差
note:这条路径不一定要是简单路径。

输入描述

第一行两个整数n,m。
接下来m行每行三个数u,v,x表示u指向v有一条权为w的边。

输出描述

 输出一行一个实数,你的答案和标准答案相对误差或者绝对误差不超过10-6就算正确。

示例1

输入:

2 1 1 2 3

输出:

0

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 620K, 提交时间: 2020-04-04 08:48:39

#include<bits/stdc++.h>
using namespace std;
#define P pair<int,int>
#define maxn 33
#define fi first
#define se second
int n,m;
vector<P>g[maxn];
int sta[maxn];
int vs[maxn];
double ans=1e9;
double pw2(double x)
{
	return x*x;
}
void cal(int l,int r)
{
	double tot=0.0;
	for(int i=l;i<=r;++i)
	tot+=sta[i];
	tot/=(r-l+1);
	double ret=0.0;
	for(int i=l;i<=r;++i)
	ret+=pw2(sta[i]-tot);
	ret/=(r-l+1);
	ans=min(ans,sqrt(ret));
}
void dfs(int u,int d)
{
	vs[u]=d;
	for(auto it:g[u])
	{
		int v=it.fi,w=it.se;
		sta[d]=w;
		if(v==n) cal(1,d);
		if(!vs[v]) dfs(v,d+1);
		else cal(vs[v],d); 
	}
	vs[u]=0;
}
int main()
{
	scanf("%d%d",&n,&m);
	while(m--)
	{
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		g[u].push_back(P(v,w));
	}
	dfs(1,1);
	printf("%.20f\n",ans);
	return 0;
}

上一题