题意:给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径。

析:首先这是一个最短路径问题,应该是BFS,因为要保证是路径最短,还要考虑字典序,感觉挺麻烦的,并不好做,事实用两次BFS,

第一次是倒序BFS,目的是得到从结点 i 到结点n的最短距离,然后再从第一个点开始到最后一个,要保证在查找时,每经过一点要让d值恰好减少1,

直到终点,这也是一个BFS,因为这个字典序在某个结点是一样的,所以是两个BFS,我超时了好几次,因为少写了一个vis, 一定要细心,

据说可以只用一次BFS,倒序,如果有兴趣可以尝试,反正我暂时没想出来,毕竟倒着字典序不好找.

再就是这个图不好构造,不能用二维数组,我用一个vector来存在,用了2*n个长度,偶数下标存结点,奇数存颜色,遍历时要注意是+2, 不是++.

代码如下:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <vector>
  5. #include <queue>
  6. #include <cstring>
  7.  
  8. using namespace std;
  9. const int maxn = 200000 + 5;
  10. const int INF = 0x3f3f3f3f;
  11. int d[maxn], vis[maxn], ans[maxn];
  12. vector<int> v[maxn];
  13. int Min(int a, int b){ return a < b ? a : b; }
  14.  
  15. void bfs1(int n){//逆序BFS
  16. memset(d, 0, sizeof(d));
  17. queue<int> q;
  18. memset(vis, 0, sizeof(vis));
  19. q.push(n);
  20. vis[n] = 1;
  21.  
  22. while(!q.empty()){
  23. int u = q.front(); q.pop();
  24. for(int i = 0; i < v[u].size(); i += 2){
  25. int t = v[u][i];
  26. if(t == 1){ d[1] = d[u] + 1; return; }//小优化,找到1就行了
  27. if(vis[t])continue;
  28. d[t] = d[u] + 1;
  29. vis[t] = 1;
  30. q.push(t);
  31. }
  32. }
  33. }
  34.  
  35. void bfs2(int n){
  36. memset(vis, 0, sizeof(vis));
  37. queue<int> q;
  38. q.push(n);
  39. vis[n] = 1;
  40. fill(ans, ans+d[1]+1, INF);
  41.  
  42. while(!q.empty()){
  43. int u = q.front(); q.pop();
  44. if(!d[u]) return ;
  45. int m = INF;
  46. for(int i = 1; i < v[u].size(); i += 2)
  47. if(d[u] == d[v[u][i-1]]+1) m = Min(m, v[u][i]);
  48.  
  49. ans[d[1]-d[u]] = Min(ans[d[1]-d[u]], m);
  50. for(int i = 0; i < v[u].size(); i += 2)
  51. if(!vis[v[u][i]] && d[u] == d[v[u][i]]+1 && v[u][i+1] == m){
  52. vis[v[u][i]] = 1;
  53. q.push(v[u][i]);
  54. }
  55. }
  56. }
  57.  
  58. int main(){
  59. // freopen("in.txt", "r", stdin);
  60. int n, m;
  61. while(scanf("%d %d", &n, &m) == 2){
  62. for(int i = 1; i <= n; ++i) v[i].clear();
  63. int x, y, w;
  64. for(int i = 0; i < m; ++i){
  65. scanf("%d %d %d", &x, &y, &w);
  66. v[x].push_back(y);
  67. v[x].push_back(w);
  68. v[y].push_back(x);
  69. v[y].push_back(w);
  70. }
  71.  
  72. bfs1(n);
  73. bfs2(1);
  74. printf("%d\n", d[1]);
  75. for(int i = 0; i < d[1]; ++i)
  76. if(!i) printf("%d", ans[i]);
  77. else printf(" %d", ans[i]);
  78. printf("\n");
  79. }
  80. return 0;
  81. }

UVa 1599 Ideal Path (两次BFS)的更多相关文章

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

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

  2. UVA 1599 Ideal Path (HDU 3760)

    两次bfs: 第一次bfs逆向搜索,得到每个点到终点的最短距离,找出最短路:第二次bfs根据最短距离可以选择满足条件的最短路. 注意!碰到这种很大数据量的题目一定要记得用scanf,printf 输入 ...

  3. UVA 1599 Ideal Path(bfs1+bfs2,双向bfs)

    给一个n个点m条边(<=n<=,<=m<=)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小.一对 ...

  4. Uva 1599 Ideal Path - 双向BFS

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

  5. UVa 1599 Ideal Path【BFS】

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

  6. uva 1599 ideal path(好题)——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGYAAAODCAYAAAD+ZwdMAAAgAElEQVR4nOy9L8/0ypH/Pa8givGiyC

  7. 【每日一题】 UVA - 1599 Ideal Path 字典序最短路

    题解:给一个1e5个点2e5条边,每个边有一个值,让你输出一条从1到n边的路径使得:条数最短的前提下字典序最小. 题解:bfs一次找最短路(因为权值都是1,不用dijkstra),再bfs一次存一下路 ...

  8. UVA 1599 Ideal Path

    题意: 给出n和m,n代表有n个城市.接下来m行,分别给出a,b,c.代表a与b之间有一条颜色为c的道路.求最少走几条道路才能从1走到n.输出要走的道路数和颜色.保证颜色的字典序最小. 分析: bfs ...

  9. UVA 11624 Fire!(两次BFS+记录最小着火时间)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

随机推荐

  1. Spring集成Mybatis(Dao方式开发)

    Spring整成Mybatis注意事项:  1. 关键jar包不能少 2.可以单独整理好Mybatis框架,测试无误再集成Spring 3.集成时,参数级别的细节可以选择忽略,但思路必须清晰 代码如下 ...

  2. C# Async&Await

    在async和await之前我们用Task来实现异步任务是这样做的: static Task<string> GetBaiduHtmlTAP() { //创建一个异步Task对象,内部封装 ...

  3. 使用C++生成1-33中的6个随机数,无重复

    生成1-33中的6个随机数,无重复 ------------------------------------------------------------------------   方法1.每生成 ...

  4. Qt添加库文件和头文件目录(QCreator)

    在使用QtCreator开发图像处理程序的时候想加入Opencv库来处理图形,添加头文件,需要编辑工程文件夹下的.pro文件在文件中添加以下内容,即可包含头文件的文件夹: INCLUDEPATH += ...

  5. 关于jQuery的$.proxy()应用.

    今天在看<<锋利的jQuery>>时看到了proxy()的使用,感觉很模糊,就到处找资料. jQuery的源码也没看明白. 不过总算明白了proxy的用法了; <inpu ...

  6. C++ - 容器概述

    一 迭代器iterator 5种类别 常用的迭代器 常用的迭代器 二 分配算符Allocators 三 容器简介 STL标准容器类简介 标准容器类 说明 顺序性容器 关联容器 容器适配器 所有标准库共 ...

  7. Jboss:The LogManager was not properly installed (you must set the "java.util.logging.manager" system prop

    可能是jboss的服务器版本选择不对 ,比如我本地的Jboss服务器版本是  jboss-as-web-7.0.2.Final,选择的服务器版本是JBOOS  V7.1  Runtime ,就会报上面 ...

  8. 归纳整理Linux下C语言常用的库函数----文件操作

    在没有IDE的时候,记住一些常用的库函数的函数名.参数.基本用法及注意事项是很有必要的. 参照Linux_C_HS.chm的目录,我大致将常用的函数分为一下几类: 1. 内存及字符串控制及操作 2. ...

  9. 07-SSH综合案例:前台用户模块:结构创建及注册页面跳转

    现在就不要直接访问一个JSP,要通过一个Action映射过去.我现在点击要去一个注册的页面 这还不是一个真正的注册,只是一个页面的跳转. 1.5.2 用户模块 注册功能: 在index.jsp页面中点 ...

  10. Cocoa Touch(三):图形界面UIKit、Core Animation、Core Graphics

    UIKit 视图树模型 1.视图树模型 计算机图形实际上是一个视图树模型,每个视图都有一个本地坐标系.每个本地坐标系的组成部分是:原点在父坐标系中的位置,每个基在父坐标系中的位置,由此就可以根据向量的 ...