题意:

给定一个有重边有自环的无向图,n个点(2 <= n <= 100000), m条边(1 <= m <= 200000), 每条边有一个权值, 求从第一个点到n的最少步数, 如果最少步数相同有多条路径, 那么输出权值字典序最小的一条。

分析:

用BFS解决最短路问题, 可以先从终点BFS, 求出每个点到终点的最短距离。 那么最少步数就是起点的最短距离, 最短路径就是从起点每次向最短距离比自己少1的顶点移动(如果有多个则可以随便走), 这样就可以保证走的是最短路径, 如果一开始我们是从起点BFS, 那么这样则不能保证走的是通往终点的最短路径。然后我们就可以从起点出发, 循环最短距离次, 每次选择字典序最少的走,  如果有多个字典序相同则选择多个, 直到走完最短距离, 就可以得出答案。 注意两次BFS都需要添加标记, 不然重边很可能就会导致TLE。

 #include <bits/stdc++.h>
using namespace std;
const int maxm = 1e7;
const int maxn = 1e6 + ;
const int inf = 1e9;
struct Node{
int v,col,next;
Node():v(),col(),next(){}
};
struct ele{
int v;
int dist;
ele(int v, int dist):v(v),dist(dist){}
}; Node edge[maxn];
int G[maxn], d[maxn];
bool vis[maxn];
int n, m, cnt; void build(){
memset(G,-,sizeof(G));
cnt = ;
for(int i = ; i < m; i++){
int u, v, col;
scanf("%d %d %d", &u, &v, &col);
if(u == v) continue;
edge[cnt].v = v;
edge[cnt].col = col;
edge[cnt].next = G[u];
G[u] = cnt++;
edge[cnt].v = u;
edge[cnt].col = col;
edge[cnt].next = G[v];
G[v] = cnt++;
}
} void revbfs(){
fill(d,d+maxn, inf);
memset(vis,,sizeof(vis));
queue<ele> q;
q.push(ele(n,));
d[n] = ;
vis[n] = ;
while(!q.empty()){
ele u = q.front(); q.pop();
d[u.v] = u.dist;
for(int i = G[u.v]; i != -; i = edge[i].next){
int v = edge[i].v;
if(d[v] < u.dist + || vis[v]){
continue;
}
q.push(ele(v,u.dist+));
vis[v] = ;
}
}
}
void bfs(){
vector<int> path;
memset(vis,,sizeof(vis));
vis[] = ;
vector<int> next;
next.push_back();
for(int i = ; i < d[]; i++){//the essential minimum step
int min_col = inf;
for(int j = ; j < next.size(); j++){
int u = next[j];
for(int k = G[u]; k != -; k = edge[k].next){
int v = edge[k].v;
if(d[u] == d[v] + )
min_col = min(min_col,edge[k].col);
}
}
//find out the minimum color
path.push_back(min_col); vector<int> next2;
for(int j = ; j < next.size(); j++){
int u = next[j];
for(int k = G[u]; k != -; k= edge[k].next){
int v = edge[k].v;
if(d[u] == d[v] + && !vis[v] && edge[k].col == min_col){
vis[v] = ;
next2.push_back(v);
}
}
}
next = next2;
} printf("%d\n%d",(int)path.size(),path[]);
for(int i = ; i < path.size(); i++){
printf(" %d",path[i]);
}
puts("");
}
int main(){
freopen("1.txt","r",stdin);
while(~scanf("%d %d", &n, &m)){
build();
revbfs();//反向bfs求出终点到每个点的最短距离
bfs();
}
printf("%.3f",(double)clock()/CLOCKS_PER_SEC);
return ;
}

UVa 1599 理想路径(反向BFS 求最短路径 )的更多相关文章

  1. UVA 816 -- Abbott's Revenge(BFS求最短路)

     UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...

  2. UVa 1599 Ideal Path【BFS】

    题意:给出n个点,m条边,每条边上涂有一个颜色,求从节点1到节点n的最短路径,如果最短路径有多条,要求经过的边上的颜色的字典序最小 紫书的思路:第一次从终点bfs,求出各个节点到终点的最短距离, 第二 ...

  3. UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)

    大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...

  4. Uva 1599 最佳路径

    题目链接:https://uva.onlinejudge.org/external/15/1599.pdf 题意: 保证在最短路的时候,输出字典序最小的路径. 方法: 路径上有了权值,可以利用图论的数 ...

  5. Uva 1599 Ideal Path - 双向BFS

    题目连接和描述以后再补 这题思路很简单但还真没少折腾,前后修改提交了七八次才AC...(也说明自己有多菜了).. 注意问题: 1.看清楚原题的输入输出要求,刚了书上的中文题目直接开撸,以为输入输出都是 ...

  6. 理想路径——双向BFS

    题目 给n个点m条边(2 ≤ n ≤ 100000,1 ≤ m ≤ 200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量的少,在此前提下,经过边的颜色序列的 ...

  7. BFS - 求最短路径

    Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. ...

  8. 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。

    这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...

  9. UVA 1599 Ideal Path(双向bfs+字典序+非简单图的最短路+队列判重)

    https://vjudge.net/problem/UVA-1599 给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色 ...

随机推荐

  1. 用jdbc连接数据库并简单执行SQL语句

    一:版本一.这种存在一个问题就是每执行一次操作都会创建一次Connection链接和且释放一次链接 1:创建pojo对象(OR映射,一个pojo类对应一张数据库表)   package com.yin ...

  2. 在代码里更新autolayout布局

    //遍历view约束(高,宽) NSArray* constrains = self.View.constraints; for (NSLayoutConstraint* constraint in ...

  3. Go 使用自定义包(package)

    自定义包的分为两种: 1.同目录下的包: 2.不同目录下的包: *经测试,同目录下是不可以用不同包的文件的 同目录下的包: 不同文件中的变量和函数都可以直接访问 不同目录下的包: 1.把要在自定义包外 ...

  4. TIME-April

    一转眼四月份又过了三分之一,现在才开始计划自己的四月还真是对自己太过放松了呀!不过前一段时间都在搞学生会的五四评优答辩,索然不是我喜欢的过程,但是结果还比较令人欢喜.翻掉过去的篇章,展开新的一页. 四 ...

  5. ACM复习专项

    资料整理 ACM训练营 邝斌的ACM模板 牛客网哈理工ACM教学视频 视频网盘资料(密码:kntr) 1. 训练阶段 第一阶段:练习经典常用算法 (本周任务) 1. 最短路(Floyd.Dijstra ...

  6. 219 Contains Duplicate II 存在重复 II

    给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使 nums [i] = nums [j],并且 i 和 j 的绝对差值最大为 k. 详见:https://leetcod ...

  7. CSS3实现边框线条动画特效

    <div class="box-line"></div> CSS代码 .box-line, .box-line::before, .box-line::af ...

  8. phpmyadmin在linux下通过sock安装教程

    当初是按照 http://www.cnblogs.com/freeweb/p/5262852.html 地址参考安装,因为疏忽,未考虑到版本差异带来的影响(自身安装的是最新版 phpMyAdmin-4 ...

  9. [转] NTFS Permission issue with TAKEOWN & ICACLS

    (转自:NTFS Permission issue with TAKEOWN & ICACLS - SAUGATA   原文日期:2013.11.19) Most of us using TA ...

  10. vb,wps,excel 提取括号的数字

    Sub 抽离数字() Dim hang Range("h1").Select Columns("E:F").Select Selection.Clear Ran ...