UVa 1599 理想路径(反向BFS 求最短路径 )
题意:
给定一个有重边有自环的无向图,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 求最短路径 )的更多相关文章
- UVA 816 -- Abbott's Revenge(BFS求最短路)
UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉 ...
- UVa 1599 Ideal Path【BFS】
题意:给出n个点,m条边,每条边上涂有一个颜色,求从节点1到节点n的最短路径,如果最短路径有多条,要求经过的边上的颜色的字典序最小 紫书的思路:第一次从终点bfs,求出各个节点到终点的最短距离, 第二 ...
- UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)
大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...
- Uva 1599 最佳路径
题目链接:https://uva.onlinejudge.org/external/15/1599.pdf 题意: 保证在最短路的时候,输出字典序最小的路径. 方法: 路径上有了权值,可以利用图论的数 ...
- Uva 1599 Ideal Path - 双向BFS
题目连接和描述以后再补 这题思路很简单但还真没少折腾,前后修改提交了七八次才AC...(也说明自己有多菜了).. 注意问题: 1.看清楚原题的输入输出要求,刚了书上的中文题目直接开撸,以为输入输出都是 ...
- 理想路径——双向BFS
题目 给n个点m条边(2 ≤ n ≤ 100000,1 ≤ m ≤ 200000)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量的少,在此前提下,经过边的颜色序列的 ...
- BFS - 求最短路径
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. ...
- 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。
这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...
- UVA 1599 Ideal Path(双向bfs+字典序+非简单图的最短路+队列判重)
https://vjudge.net/problem/UVA-1599 给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色 ...
随机推荐
- Java Genericity
四. Java Genericity 1. Genericity 泛型 泛型 <T> 1. 泛型就是参数化类型 2. 作用:安全,方便 3. 适用于对多种数据类型执行相同功能的代码,主 ...
- C++中的四种强制类型转换符详解
阅读目录 C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非con ...
- multiset || 线段树 HDOJ 4302 Holedox Eating
题目传送门 题意:一个长度L的管子,起点在0.n次操作,0 p表示在p的位置放上蛋糕,1表示去吃掉最近的蛋糕(如果左右都有蛋糕且距离相同,那么吃同方向的蛋糕),问最终走了多少路程 分析:用multis ...
- 使用dubbox开发REST应用
新建项目,添加Maven支持. 在pom.xml中添加依赖. <dependency> <groupId>org.jboss.resteasy</groupId> ...
- GC_CONCURRENT freed 循环不停打印日志
打印类似如下语句: 03-07 19:21:49.562: D/dalvikvm(1677): GC_CONCURRENT freed 2859K, 20% free 12020K/15011K, p ...
- 在 c#中 如何 重新激活一个控件
比如toolBar是一个组合控件 this.toolBar.CaptionHeight =this.toolBar.Items.Count * 60;//重新激活toolBar控件 CaptionHe ...
- 454 4Sum II 四数相加 II
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0.为了使问题简单化,所有的 A, ...
- WAMP配置虚拟目录
1.启动wamp所有服务,输入localhost或localhost:端口号确保wamp环境正常无误. 2.设置httpd.conf 2.1打开文件:单击wamp在电脑右下角的图标=>wamp= ...
- NBA15-16赛季半程有感
2015-2016 新赛季NBA已经开打半程又多了,这半个赛季我们见证了 勇士的三节打卡:骑士的磨合反复:马刺的老骥伏枥: 当然还有窝火的XJBD. 豪哥200W刀签约黄蜂,打出来800W刀的身价,无 ...
- [BZOJ1025][SCOI2009]游戏 DP+置换群
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题目中的排数就是多少次回到原来的序列.很显然对于题目所描述的任意一种对应法则,其中一 ...