EOJ Monthly 2017.12 - F1. 不见了的人口数据 (Easy) (高斯消元)

针对星光镇因意外丢失的人口普查数据,通过保留下来的政府大楼收益评估函数逆向求解,利用高斯消元法成功恢复了各居民点的人口数量。

F1. 不见了的人口数据 (Easy)

Time limit per test: 1.0 seconds

Memory limit: 256 megabytes

星光镇的地图是有 n 个点,n1 条路,这些点从 1 到 n 编号,两两之间都可达;这 n1 条路的长度都是 1

这 n 个点是居民聚居点,第 i 个点上有 ai 个居民。去年的时候,星光镇政府曾经做了个人口普查,他们投入了大量的资金,获知了所有节点的 ai,而获知的目的,就是为新政府大楼的选址做准备的。由于新政府大楼一定会建在一个居民聚居点上,所以星光镇政府求出了对于每个聚居点 j 的「政府大楼收益评估函数」:

pj=i=1ndis(i,j)ai

其中 dis(i,j) 是 i,j 号点之间的最短距离。特别的,dis(i,i)=0

新政府大楼造好了,政府自然而然地进行了一些证据销毁工作,同时「一不小心」销毁了重金得来的人口普查数据:也就是说 ai 都丢失了。但是巧的是,所有的收益评估函数值 p1,p2,,pn 竟然都留存了下来。星光镇数据研究所唐纳德博士表示:「从这些函数值中,我们完全可以将所有的人口数据都反求出来。」但是唐纳德博士,虽然是一个著名的数学天才,但却很有可能是一个假博士,他这话自然不能当真。所以当星光镇政府又要造一个新的政府大楼,又要用到这些人口数据时,他们花费了巨资进行再调查。

身在异国的你听到此事后大笑不止,利用 p1,p2,,pn 轻轻松松地求出了 a1,a2,a3,,an

Input

输入具有如下形式:

nu1 v1un1 vn1p1 p2  pn1 pn

第一行一个整数 n

接下来 n1 行,每行两个整数 ui,vi (1ui,vin),分别表示这 n1 条路。这 n1 条路都可以双向通行。两个居民聚居点之间不会有多条路相连,也不会有一条路的两端连接了同一个居民聚居点。

最后一行,用空格隔开的 n 个整数 p1,p2,,pn,表示收益评估函数。

数据保证答案有解,并且满足 0a1,a2,,an1 000

数据规模约定:

  • 对于 Easy 档:1n100
  • 对于 Hard 档:1n250 000

Output

依次序输出 a1,a2,,an。如果有多解,输出任意解。

Examples

input
2
1 2
11 9
output
9 11
input
6
1 2
1 3
3 4
3 5
5 6
32 45 19 28 16 21
output
0 1 2 3 4 5

因为easy题数据小,可以解方程做。

高斯消元模板拉kuangbin。

注意精度,卡了一万次。

(但我觉得解法肯定不是这样做的,但我菜啊


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define LL long long
#define eps 1e-8
const int maxn=1000;
double a[maxn][maxn],x[maxn];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
int equ,var;//方程数和未知数个数
int Gauss()
{
	int i,j,k,col,max_r;
	for(k=0,col=0;k<equ&&col<var;k++,col++) {
		max_r=k;
		for(i=k+1;i<equ;i++)
			if(fabs(a[i][col])>fabs(a[max_r][col]))
				max_r=i;
		if(fabs(a[max_r][col])<eps)
			return 0;
		if(k!=max_r) {
			for(j=col;j<var;j++)
				swap(a[k][j],a[max_r][j]);
			swap(x[k],x[max_r]);
		}
		x[k]/=a[k][col];
		for(j=col+1;j<var;j++)
			a[k][j]/=a[k][col];
		a[k][col]=1;
		for(i=0;i<equ;i++)
			if(i!=k) {
				x[i]-=x[k]*a[i][k];
				for(j=col+1;j<var;j++)
					a[i][j]-=a[k][j]*a[i][col];
				a[i][col]=0;
			}

	}
	return 1;

}
int head[maxn],nxt[maxn],sz=0,to[maxn];

void add(int u,int v)
{
	nxt[sz]=head[u];
	to[sz]=v;
	head[u]=sz++;
}
void dfs(int u,int pre,double now,int x)
{
	a[x][u]=now;
	for(int i=head[u];~i;i=nxt[i]){
		int v=to[i];
		if(v==pre) continue;
		dfs(v,u,now+1,x);
	}
}
int main()
{
	for(int i=0;i<=111;i++) head[i]=-1;
	memset(a,0,sizeof a);
	memset(x,0,sizeof x);
	sz=0;
	int n;
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		u--;
		v--;
		add(u,v);
		add(v,u);
	}
	for(int i=0;i<n;i++){
		double p;scanf("%lf",&p);
		x[i]=p;
	}
	for(int i=0;i<n;i++){
		dfs(i,-1,0,i);
	}
	equ=n;
	var=n;
	Gauss();
	for(int i=0;i<n;i++){
		for(int k=0;k<=1000;k++){
			if(fabs(x[i]-k)<eps){
				printf("%d%c",k,i==n-1?'\n':' ');
			}
		}
	}

}







标题基于Spring Boot的音乐播放网站设计与实现研究AI更换标题第1章引言介绍音乐播放网站的研究背景、意义、国内外现状及论文方法与创新点。1.1研究背景与意义阐述音乐播放网站在当今数字化时代的重要性与市场需求。1.2国内外研究现状分析国内外音乐播放网站的发展现状及技术特点。1.3研究方法以及创新点概述论文采用的研究方法及在设计与实现上的创新点。第2章相关理论与技术基础总结音乐播放网站设计与实现所需的相关理论和技术。2.1Spring Boot框架介绍介绍Spring Boot框架的基本原理、特点及其在Web开发中的应用。2.2音乐播放技术概述概述音乐播放的基本原理、流媒体技术及音频处理技术。2.3数据库技术选型分析适合音乐播放网站的数据库技术,如MySQL、MongoDB等。第3章系统设计详细介绍音乐播放网站的整体设计方案。3.1系统架构设计阐述系统的层次结构、模块划分及各模块的功能。3.2数据库设计介绍数据库表结构、关系及数据存储方式。3.3界面设计用户界面的设计原则、布局及交互方式。第4章系统实现详细介绍音乐播放网站的具体实现过程。4.1开发环境与工具介绍开发所需的软件、硬件环境及开发工具。4.2核心功能实现阐述音乐播放、搜索、推荐等核心功能的实现细节。4.3系统测试与优化介绍系统测试的方法、过程及性能优化策略。第5章研究结果与分析呈现音乐播放网站设计与实现的研究结果。5.1系统功能测试结果展示系统各项功能的测试结果,包括功能完整性、稳定性等。5.2用户反馈与评价收集并分析用户对音乐播放网站的使用反馈与评价。5.3对比方法分析将本设计与实现与其他类似系统进行对比分析,突出优势与不足。第6章结论与展望总结音乐播放网站设计与实现的研究成果,并展望未来发展方向。6.1研究结论概括音乐播放网站设计与实现的主要成果及创新点。6.2展望指出当前研究的不足,提出未来改进方向及可
### 关于 EOJ 3681 的中位数问题解析 #### 题目概述 题目描述了一张由 \( n \) 个点和 \( m \) 条边组成的有向无环图 (DAG),其中每个节点具有一个点权 \( A_i \)[^2]。目标是找到从起点 \( 1 \) 到终点 \( n \) 所有可能路径中的最大中位数值。 --- #### 解题思路分析 为了求解此问题,需考虑以下几个方面: 1. **定义中位数** 对于一条路径上的点权序列,假设其长度为奇数,则中位数为按升序排列后的中间值;若长度为偶数,则通常取两个中间值的平均值作为中位数。 2. **二分查找法的应用** 要最大化路径的中位数,可以通过二分查找来逼近最优解。设定初始范围为所有点权的最大值和最小值之间,并逐步缩小范围直到满足精度条件(即绝对或相对误差小于 \( 10^{-4} \))[^3]。 3. **验证候选中位数的有效性** 给定当前猜测的中位数 \( mid \),通过调整权重重新构建图模型:将大于等于 \( mid \) 的点赋正权值,其余点赋负权值。随后利用动态规划或其他算法判断是否存在总权重非负的可行路径。 4. **实现细节** - 使用拓扑排序处理 DAG 图结构。 - 动态维护前缀和数组以便快速计算子路径权重之和。 以下是基于上述逻辑的具体代码实现: ```python from collections import deque, defaultdict def can_find_non_negative_path(graph, weights, threshold): """检查是否存在一条路径使得经过调整后的权重和 >= 0""" dp = [-float('inf')] * len(weights) order = topological_sort(graph) for node in order: if weights[node] >= threshold: current_weight = 1 else: current_weight = -1 dp[node] = max(dp[node], current_weight) for neighbor in graph.get(node, []): dp[neighbor] = max(dp[neighbor], dp[node]) return dp[-1] >= 0 def topological_sort(graph): """对给定的 DAG 进行拓扑排序""" indegree = {node: 0 for node in range(len(graph))} queue = deque() for u in graph: for v in graph[u]: indegree[v] += 1 for node in indegree: if indegree[node] == 0: queue.append(node) result = [] while queue: curr = queue.popleft() result.append(curr) for next_node in graph[curr]: indegree[next_node] -= 1 if indegree[next_node] == 0: queue.append(next_node) return result def find_max_median(n, edges, values): """主函数用于寻找最大中位数""" INF = float('inf') low, high = min(values), max(values) precision = 1e-5 graph = defaultdict(list) # 构建邻接表表示的图 for a, b in edges: graph[a].append(b) best_mid = -INF while abs(high - low) > precision: mid = (low + high) / 2 if can_find_non_negative_path(graph, values, mid): best_mid = max(best_mid, mid) low = mid else: high = mid return round((best_mid + low) / 2, 5) # 输入样例测试部分省略... ``` --- #### 复杂度分析 - 时间复杂度主要取决于二分次数以及每次验证操作的时间开销。假设有 \( k \) 层次迭代完成二分过程,则整体时间复杂度大约为 \( O(k \cdot E) \),其中 \( E \) 表示边的数量。 - 空间复杂度则受存储图数据结构的影响,约为 \( O(V+E) \),\( V \) 和 \( E \) 分别代表顶点数目与边数量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值