题意:

给定一个有重边有自环的无向图,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. 在JS/jQuery中,怎么触发input的keypress/keydown/keyup事件?

    怎么触发keypress/keydown/keyup事件? 问题: 1.在之前的写的input后面添加了搜索按钮 2.input只有keyup事件,如下: $("#desktop_folde ...

  2. c语言程序设计案例教程(第2版)笔记(五)-软件开发基础知识

    零散知识点: 软件的主要特征 软件是一种逻辑产品,而不是有型的物质: 软件需要设计.开发,但不是传统意义上的产品制造: 软件不会磨损,但软件需要维护,即:修改代码或增加模块: 虽然软件行业正在向基于组 ...

  3. [POI2008]激光发射器SZK

    Description 多边形相邻边垂直,边长为整数,边平行坐标轴.要在多边形的点上放一些激光发射器和接收器.满足下列要求: 1发射器和接收器不能放置在同一点: 2发射器发出激光可以沿壁反射,最终到达 ...

  4. poj 1061 青蛙约会(扩展欧几里德)

    题目链接: http://poj.org/problem?id=1061 题目大意: 中文题目,题意一目了然,就是数据范围大的出奇. 解题思路: 假设两只青蛙都跳了T次,可以列出来不定方程:p*l + ...

  5. Data Center Maintenance CodeForces - 950E

    http://codeforces.com/contest/950/problem/E 贴一份板子 #include<cstdio> #include<vector> #inc ...

  6. jmeter(二)元件的作用域与执行顺序

    1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...

  7. js 常用处理

    判断浏览器环境是PC端还是手机端 function goPAGE() { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios| ...

  8. AJPFX:关于面向对象及java的一些机制的思考

    1.变量的作用域和生命周期什么关系? 2.java除了在类体和方法体(包括参数)中可以声明变量外,其他位置一定不可以声明变量吗?比如高级别的应用里是不是有例外呢? 3.java源文件中代码的组织方式一 ...

  9. 洛谷 P1569 [USACO11FEB]属牛的抗议Generic Cow Prote…

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row and numbered 1..N. The cow ...

  10. MAC 添加共享,脚本执行

    Linux需要首先安装 yum install samba-client linxu添加windows 公共盘  mount -t cifs  user=guest,password=guest // ...