UVA 1599 Ideal Path (理想路径)
来源:互联网 发布:判断数据上升趋势算法 编辑:程序博客网 时间:2024/03/28 20:39
【题意】
给一个n个点m条边(2<=n<=100000,1<=m<=200000)的无向图,每条边上都涂有一种颜色。求从结点
1到结点n的最短路径,在此前提下,经过边的颜色序列的字典序最小。一对结点间可能有多条边,一条边
可能连接两个相同结点。输入保证结点1可以到达结点n。颜色为1~10^9的整数。
【分析】
1. 本题是不错的bfs题,因为数据太大,如果直接找绝对超时。
2. 题目给的n小于等于100000,所以不能用邻接矩阵来保存,只能通过邻接表,用邻接表保存还方便进
行遍历,用结构体保存邻接表,同时记录颜色的数值。
3. 题目中无向图可能有自环和重边,自环可以在输入的时候省略掉,重边因为在输入的时候无法判断是
否最短,所以保存下来,再用此点时,再进行遍历选取最短。
【思路】
1. 先倒着bfs,得到每一个结点i到终点的最少步数d[i],然后再从起点出发,每次到达一个新结点时保
证d值恰好减少1,直到到达终点。
2. 倒着bfs,保存每一个结点i到终点的最小步数,就相当于一个层次图,将于每个离终点相同的点放在
一个层次里,再从起点开始,一层一层的走,避免了1个点多次用到。
3. 用queue和vector来进行层次图的路径的操作,用queue保存层次的点,vector保存本层次的对应的结
构体的坐标,中间有太多细节需要考虑。每走一点清一次queue,每走一层清空一次vector。标记数组记录
某点是否走过,避免重走。
4. 因为事先求出了每点i到终点的最短路径d[i],所以不用保存路径,只需求出当前步中最小的颜色的数
值,就是最优的解,直接输出就行。
【代码】
#include<stdio.h>#include<string.h>#include<vector>#include<queue>#include<iostream>using namespace std;const int MAXN=100000+5;const int MAXM=200000+5;const int INF=0x3f3f3f3f;struct node{ int x; int color; int next;} G[MAXM*2];int head[MAXN],d[MAXN];bool book[MAXN];int n,m,cnt;void Addedge(int a,int b,int c){ G[cnt].x=b; G[cnt].color=c; G[cnt].next=head[a]; head[a]=cnt++;}void Bfs1(){ queue<int>p; d[n]=0; p.push(n); while(!p.empty()) { int x=p.front(); p.pop(); if(x==1) { printf("%d\n",d[x]); return ; } for(int i=head[x]; i!=-1; i=G[i].next) { int k=G[i].x; if(d[k]!=-1) continue; p.push(k); d[k]=d[x]+1; } } return ;}void Bfs2(){ queue<int>p; // 保存下一步的点 vector<int>Vec; // 保存结构体的下坐标 p.push(1); book[1]=true; int color=INF; while(!p.empty()||Vec.size()) { if(p.empty()) { int len=Vec.size(); for(int i=0; i<len; i++) { int k=Vec[i]; int x=G[k].x; if(G[k].color==color&&!book[x]) { if(x==n) { printf("%d\n",color); return ; } p.push(x); book[x]=true; } } printf("%d ",color); Vec.clear(); color=INF; } int k=p.front(); p.pop(); for(int i=head[k]; i!=-1; i=G[i].next) { int x=G[i].x; if(d[k]-d[x]==1&&G[i].color<=color) { Vec.push_back(i); color=G[i].color; } } } return ;}int main(){ while(~scanf("%d %d",&n,&m)) { memset(head,-1,sizeof(head)); memset(d,-1,sizeof(d)); memset(book,false,sizeof(book)); cnt=0; int a,b,c; for(int i=0; i<m; i++) { scanf("%d %d %d",&a,&b,&c); Addedge(a,b,c); Addedge(b,a,c); } Bfs1(); Bfs2(); } return 0;}
【收获】
本题是到不错的bfs题,考了很多内容,queue、vector、邻接表、双向bfs,使一个大数据的题,得到很好 的解决。
尤其是倒着bfs构成一个层次图,直接能求出最短路径的长度,还为下面走的路径指明了方向,节约了代码 的时间复杂度和提供了准确的路径。
- UVA 1599 Ideal Path (理想路径)
- 理想路径(Ideal Path,UVa 1599)
- 例题6-20 UVA 1599 Ideal Path理想路径
- uva 1599 - Ideal Path
- UVa 1599 Ideal Path
- Uva - 1599 - Ideal Path
- UVa 1599 Ideal Path
- UVa 1599 Ideal Path
- UVA 1599 Ideal Path
- uva UVA - 1599 Ideal Path
- UVa 1599 - Ideal Path(BFS)
- uva 1599 Ideal Path (两次bfs)
- 最短路+字典序最小+输出路径(Ideal Path,UVA 1599)
- UVA 1599(p173)----Ideal Path
- 例题6-20 理想路径(Ideal Path, NEERC 2010, UVa1599)
- uva 1599 ideal path(好题)——yhx
- uva 1599 ideal path(好题)——yhx
- UVA 1599 Ideal Path 【两次BFS+贪心】 (好题)
- Spark Streaming性能优化: 如何在生成环境下应对流数据峰值巨变
- 删除排序数组中的重复数字 II
- PHP生成唯一的促销/优惠/折扣码,由字母和数字组成。
- EasyUI DataGrid绑定嵌套的json数据
- codeforces Round 377 Div2 E
- UVA 1599 Ideal Path (理想路径)
- 1185 威佐夫游戏 V2 博弈论 + 大整数乘法
- 对称加密
- Ant体验
- 367. Valid Perfect Square
- Android动画资源
- POJ 2965 - 状态压缩 + BFS
- AS与.net的交互——详解UrlRequest
- Java使用增强for循环和迭代器遍历Map集合