image
(没穿红色的可莉……)

题目描述

给定一张 \(n\) 个点 \(m\) 条边的连通图,每条边有权值 \(w\) ,定义从 \(u_1\)\(u_x\) 经过边 \(e_1,e_2,…,e_k\) 的路径长度为:

请分别对于每个点 \(i∈[2,n]\) 求出点 \(1\)\(i\) 的长度最小的路径。

输入格式

第一行两个数,代表 \(n,m\)

接下来 \(m\) 行每行三个数 \(u,v,w\),代表一条连接 \(u,v\) 长度为 \(w\) 的边。

输出格式

对于每个 \(i\) 输出点 \(1\)\(i\) 长度最小的路径的长度,用空格分隔。

样例 #1

样例输入 #1

5 4
5 3 4
2 1 1
3 2 2
2 4 2

样例输出 #1

1 2 2 4

提示

【样例解释】

  • \(i=2\) 时经过路径 \(1→2\)
  • \(i=3\) 时经过路径 \(1→2→3\)
  • \(i=4\) 时经过路径 \(1→2→4\)
  • \(i=5\) 时经过路径 \(1→3→5\)

【数据范围】

对于 \(30\%\) 的数据,\(1≤n≤1000\)

对于另 \(30\%\)的数据,\(m=n-1\)

对于 \(100\%\) 的数据,\(1≤n,m≤1×10^5;0≤w_i≤10^9\)

解析

对于题干中的路径长度定义我们可以这样理解:将最长边的边权变为0,最短边的边权变成两倍,相当于有两次操作(对于一条路径有且仅能有这两个操作),我们可以用分层图的思想(一共建4层),首先每层都由x向y连z的无向边,第一层向第二层连边权为0的边,再向第三层连2倍边权的边,第二层向第四层连2倍边权,第三层向第四层连0边(巧妙的建图方法)对于一种操作向上连边,这样保证第四层都是有两次操作的,其实2.3层相当于是一个过渡,最后的答案就是第一层和第四层的d[]取min,那么答案为什么是这个呢?因为1->i可能直接相连,那么答案就是在第一层中找(只有一条边不可能还进行两次操作),答案统计过程包含了对该种情况的特判。求d[]用最短路算法就行了,我这里用的spfa。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, m, tot, head[N], to[N << 3], nxt[N << 3], w[N << 3], d[N];
bool vis[N];
void add(int x, int y, int z) {
	nxt[++ tot] = head[x]; head[x] = tot; to[tot] = y; w[tot] = z;
}
void spfa() {
	memset(d, 0x3f, sizeof d);
	queue<int> q;
	d[1] = 0, q.push(1); vis[1] = 1;
	while (!q.empty()) {
		int u = q.front(); q.pop(); vis[u] = 0;
		for (int i = head[u]; i; i = nxt[i]) {
			int v = to[i];
			if (d[v] > d[u] + w[i]) {
				d[v] = d[u] + w[i];
				if (!vis[v]) {
					vis[v] = 1;
					q.push(v);
				}
			}
		}
	}
}
signed main() {
	cin >> n >> m;
	for (int i = 1; i <= m; i ++) {
		int u, v, w; cin >> u >> v >> w;
		for (int i = 0; i <= 3; i ++) {
			add(u + i * n, v + i * n, w);
			add(v + i * n, u + i * n, w);
		}
		add(u, v + n, 0), add(v, u + n, 0);
		add(u, v + 2 * n, 2 * w), add(v, u + 2 * n, 2 * w);
		add(u + n, v + 3 * n, 2 * w), add(v + n, u + 3 * n, 2 * w);
		add(u + 2 * n, v + 3 * n, 0), add(v + 2 * n, u + 3 * n, 0);
	}
	spfa();
	for (int i = 2; i <= n; i ++) {
		int ans = min(d[i], d[i + 3 * n]);
		printf("%lld ", ans); 
	}
	return 0;
}

image

原文地址:http://www.cnblogs.com/YHxo/p/16792745.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性