当前位置:网站首页>理想路径问题
理想路径问题
2022-06-26 15:45:00 【chengqiuming】
一 问题描述
给定一个有 n 个节点,m 条边的无向图,每边都涂有1种颜色。求节点1到n的一条路径,使得经过的边数最少,在此前提前,经过边的颜色序列最小。可能有自环和重边。
二 输入和输出
1 输入
输入共 m+1 行,第1行包括两个整数:m和n。之后的m行,每行都包含3个整数a、b、c,表示a和b之间有一条颜色为c的路径。
2 输出
输出共两行,第1行包含正整数k,表示节点1到n至少需要经过k条边。第2行包含k个由空格隔开的正整数,表示节点1到n经过的边的颜色。
3 输入样例
4 6
1 2 1
1 3 2
3 4 3
2 3 1
2 4 4
3 1 1
4 输出样例
2
1 3
节点1到4至少经过两条边:1 > 3,颜色为1(最后输入的那条边);3 > 4,颜色为3。
三 分析
本问题求解节点1到n的最短距离,在此前提下,色号序列最小。可以先求最短距离,然后考察色号。因为在从节点1出发的多条边中,并不知道哪条边是最短路径上的边,所以无法确定最小色号。
四 算法设计
1 从节点n反向广度优先遍历标高,节点1的高度正好为从节点1到n的最短距离。
2 从节点1正向广度优先遍历,沿着高度减1的方向遍历,找色号小的点,如果多个色号都最小,则考察下一个色号哪个最小,直到节点n结束。

五 图解分析
1 根据输入样例创建图,然后节点n反向广度优先遍历标高,节点1的高度为2,即节点1到n的最短距离为2,输出2。
2 从节点1正向广度优先遍历,沿着高度减1的方向遍历,找边商色号小的邻接点,节点1到2的色号为1,节点1到3的色号为1,节点1到3的另外一条道路色号为2,最小色号为1,输出1,。目前无法确定选择哪条边,因此将可能走的两个邻接点2和3入队并暂存。
3 从节点2和节点3出发,沿着高度减1的方向遍历,找边上色号小的邻接点,节点2到4的色为4,节点3到4的色号为3,最小色号为3,输出3。
六 代码
package graph.uva1599;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class UVA1599 {
static final int inf = 0x7fffffff;
static final int N = 100000 + 5;
static final int M = 200000 + 5;
static int n;
static int m;
static int cnt;
static boolean vis[];
// 保存节点号
static Queue<Integer> q1 = new LinkedList<>();
// 保存色号
static Queue<Integer> q2 = new LinkedList<>();
// 保存色号最小的边关联的邻接点号
static Queue<Integer> q3 = new LinkedList<>();
static int head[];
static int dis[] = new int[N];
static Edge e[] = new Edge[M];
static {
for (int i = 0; i < e.length; i++) {
e[i] = new Edge();
}
}
// 添加一条边
static void add(int u, int v, int c) {
e[++cnt].to = v;
e[cnt].c = c;
e[cnt].next = head[u];
head[u] = cnt;
}
// 逆向标高求最短距离
static void bfs1() {
int u, v;
vis = new boolean[N];
dis[n] = 0;
q1.add(n);
vis[n] = true;
while (!q1.isEmpty()) {
u = q1.peek();
q1.poll();
vis[u] = true;
for (int i = head[u]; i > 0; i = e[i].next) {
v = e[i].to;
if (vis[v])
continue;
dis[v] = dis[u] + 1;
q1.add(v);
vis[v] = true;
}
}
}
// 正向求色号序列
static void bfs2() {
int u, v, minc, c;
boolean first = true;
vis = new boolean[N];
vis[1] = true;
// 1号结点所有邻接点
for (int i = head[1]; i > 0; i = e[i].next)
// 高度减1的邻接点
if (dis[e[i].to] == dis[1] - 1) {
q1.add(e[i].to);
q2.add(e[i].c);
}
while (!q1.isEmpty()) {
minc = inf;
while (!q1.isEmpty()) {
v = q1.peek();
q1.poll();
c = q2.peek();
q2.poll();
if (c < minc) {
while (!q3.isEmpty()) // 发现更小队列清空
q3.poll();
minc = c;
}
if (c == minc)
q3.add(v);
}
if (first)
first = false;
else
System.out.print(" ");
System.out.print(minc);
while (!q3.isEmpty()) { // 所有等于最小色号的结点
u = q3.peek();
q3.poll();
if (vis[u])
continue;
vis[u] = true;
for (int i = head[u]; i > 0; i = e[i].next) { // 扩展每一个结点
v = e[i].to;
if (dis[v] == dis[u] - 1) {
q1.add(v);
q2.add(e[i].c);
}
}
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int u, v, c;
while (true) {
n = scanner.nextInt();
m = scanner.nextInt();
head = new int[N];
for (int i = 0; i < head.length; i++) {
head[i] = 0;
}
cnt = 0;
for (int i = 1; i <= m; i++) {
u = scanner.nextInt();
v = scanner.nextInt();
c = scanner.nextInt();
add(u, v, c);
add(v, u, c);
}
bfs1();
System.out.println(dis[1]);
bfs2();
System.out.println();
}
}
}
class Edge {
int to;
int c;
int next;
}七 测试
绿色为输入,白色为输出。

边栏推荐
- STEPN 新手入门及进阶
- Golang 1.18 go work usage
- 【leetcode】331. Verifying the preorder serialization of a binary tree
- [graduation season · advanced technology Er] what is a wechat applet, which will help you open the door of the applet
- 【leetcode】701. Insert operation in binary search tree
- Anaconda3 installation tensorflow version 2.0 CPU and GPU installation, win10 system
- 【leetcode】48. Rotate image
- (1) Keras handwritten numeral recognition and recognition of self written numbers
- Handwritten numeral recognition, run your own picture with the saved model
- 简单科普Ethereum的Transaction Input Data
猜你喜欢
![[file] VFS four structs: file, dentry, inode and super_ What is a block? difference? Relationship-- Editing](/img/b6/d288065747425863b9af95ec6fd554.png)
[file] VFS four structs: file, dentry, inode and super_ What is a block? difference? Relationship-- Editing

STEPN 新手入门及进阶

Super double efficiency! Pycharm ten tips

TweenMax+SVG切换颜色动画场景

NFT transaction principle analysis (1)

svg野人动画代码

李飞飞团队将ViT用在机器人身上,规划推理最高提速512倍,还cue了何恺明的MAE...

如何辨别合约问题

Canvas three dot flashing animation

PCIe Capabilities List
随机推荐
【leetcode】331. Verifying the preorder serialization of a binary tree
golang 临时对象池优化
4 自定义模型训练
(1) Keras handwritten numeral recognition and recognition of self written numbers
NFT 项目的开发、部署、上线的流程(2)
11 cnn简介
【leetcode】48.旋转图像
手写数字体识别,用保存的模型跑自己的图片
JS creative icon navigation menu switch background color
【思考】在买NFT的时候你在买什么?
[CEPH] Lock Notes of cephfs
4 custom model training
5 模型保存与加载
[graduation season · advanced technology Er] what is a wechat applet, which will help you open the door of the applet
Everyone is a scientist free gas experience Mint love crash
Solana capacity expansion mechanism analysis (1): an extreme attempt to sacrifice availability for efficiency | catchervc research
HW safety response
Failed to get convolution algorithm. This is probably because cuDNN failed to initialize
Canvas three dot flashing animation
6 自定义层