UVA1599-字典序+BFS
来源:互联网 发布:网络男生悲伤情歌 编辑:程序博客网 时间:2024/04/30 19:43
第一次写这么复杂的bfs,卡了我近一周,需要注意的细节很多,很多地方感觉跟题解差不多,但是就是不对。失之毫厘谬以千里啊。
这里是原题
这里是我当时看的一个比较好的题解(里面用的指针我不懂 但思路非常棒)
大概做法
先从n开始bfs,得到每个点到n的最短距离d[i]。然后从起点开始bfs,每一步保证d[v]=d[u]-1,同时储存最小字典序
代码
#include<cstdio>#include<iostream>#include<cstring>#include<vector>#include<queue>#include<algorithm>#define maxn 100005using namespace std;typedef struct edge{ int col,to; edge(int a,int b):to(a),col(b){}}Edge;vector <Edge>e[maxn]; //邻接表储存图int n,m,u,v,c,d[maxn],ans[maxn*4];//uvc是临时变量 个人习惯bool vis[maxn];void init(){ memset(ans,0x3f,sizeof ans); memset(d,-1,sizeof d); memset(vis,0,sizeof vis); for (int i=1;i<=n;i++)e[i].clear(); for(int i=1;i<=m;++i){ int a,b,c; scanf("%d%d%d",&a,&b,&c); if(a==b)continue; e[a].push_back(edge(b,c)); e[b].push_back(edge(a,c)); //双向边 } return ;}void fbfs(){ queue<int >q; q.push(n); d[n]=0; while(!q.empty()){ u=q.front(); q.pop(); // if(u==1){return ;}这里建议大家把图遍历全,不要贪图那一点点时间,不然会出现玄学bug for(int i=0,len=e[u].size();i<len;++i){ v=e[u][i].to; if(d[v]!=-1)continue;//不重复访问 写过复杂图bfs的应该都懂 d[v]=d[u]+1; q.push(v); } } return ;}void bfs(){/*这个题有一点很重要,需要先在这里说明,一不能简单更新ans(见图2),二每个点会入队多遍但只会访问一遍(见题中样例,如果每个点只入队一遍就会错过后来的更优解)这些在我下面的代码里都有所体现*/ queue<pair<int,int> >q; //这里很秒 first 储存节点编号,second储存访问到达这个节点的边的颜色 我也是看别人代码学会的 q.push(make_pair(1,0)); ans[0]=0;// while(!q.empty()){ u=q.front().first; c=q.front().second; q.pop(); if(ans[d[1]-d[u]]!=c||u==n||vis[u])continue; //一满足沿着最短路线走 二别走过 三只访问一遍即可 vis[u]=1; for(int i=0,len=e[u].size();i<len;++i){ v=e[u][i].to; c=e[u][i].col; if(d[u]!=d[v]+1||c>=ans[d[1]-d[v]])continue; ans[d[1]-d[v]]=c;//更新第(d[1]-d[v])步最小颜色 } for(int i=0,len=e[u].size();i<len;++i){ v=e[u][i].to; c=e[u][i].col; if(d[u]!=d[v]+1||c!=ans[d[1]-d[v]])continue; //如果有多个当前最优解 把他们全部入队 q.push(make_pair(v,c)); } //有可能当前阶段有多个解能到达点i,但到达点i的路径颜色不同或相同,这时就会通过开头的剪枝,将他们去掉 因为将该层遍历完后一定能得到最优解的颜色 就可以通过比较ans[]只访问最优解, 并通过vis只访问一次最优解 }}int main(){ while(scanf("%d%d",&n,&m)==2){ init(); fbfs();//从n开始 bfs();//从1开始 printf("%d\n", d[1]); for (int i = 1; i<=d[1]; i++) printf("%d%c",ans[i],i==d[1]?'\n':' '); } return 0;}
阅读全文
0 0
- UVA1599-字典序+BFS
- 例题6-20 uva1599 Ideal Path (双向bfs+字典序)
- Ideal Path,uva1599/hdu 3760(最短路中字典序最小的路径)
- 例题6-20 UVa1599 Ideal Path(两次BFS)
- uva1599 bfs双向遍历 利用数组保存中间结果
- hdu1430 魔板(双向bfs+输出路径+字典序最小)
- bfs+预处理+路径回溯+字典序最小+hash
- leetcode 332. Reconstruct Itinerary BFS多叉树的最小字典序
- POJ 2697 字典树 + bfs
- UVa1599 - Ideal Path
- UVA1599 Ideal Path
- UVa1599/poj 3967 Ideal Path
- HDU 3760 Ideal Path 最短路spfa+BFS 字典序最小的最短路
- HDU 5335 Walk Out(Bfs搜索字典序最小的最短路)
- [bfs 分层图 字典序 最短路] BZOJ 2644 Pku3967 Ideal Path
- 字典树的使用 poj1451(字典树+BFS+剪枝)
- ZZULIOJ 1426: 字典树again【字典树+bfs】
- POJ 1451 T9(字典树+bfs)
- spring学习之requestmapping详解
- 用redis分布式缓存实现
- 图床
- cd命令
- CMake使用教程
- UVA1599-字典序+BFS
- 更改文件夹及子文件的 用户和组别
- SSH框架--登录
- appium服务关键字
- Android App 瘦身总结 第二章 jni动态库及cpu兼容
- Discuz!教程之论坛开启了版块子域名绑定,如果避免多域名访问帖子和重复收录
- Spring Boot之HelloWorld环境搭建!!!
- 欢迎使用CSDN-markdown编辑器
- TensorFlow学习日记6