题目链接:https://vjudge.net/problem/UVA-1599

题目分析与翻译摘自《算法禁赛入门经典》

题目大意

  给一个 n 个点 m 条边(2 ≤ n ≤ 100000,1 ≤ m ≤ 200000)的无向图,每条边上都涂有一种颜 色。求从结点 1 到结点 n 的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小。一对结点间可能有多条边,一条边可能连接两个相同结点。输入保证结点 1 可以达到结点 n。颜色为 1~109 的整数。

分析

从终点开始“倒着”BFS,得到每个结点 i 到终点的最短距离 d[i],然后直接从起点开始走,但是每次到达一个新结点时要保证 d 值恰好减少 1(如有多个选择则可以随便走),直到到达终点。可以证明:这样走过的路径一定是一条最短路。
从起点开始按照上述规则走,如果有多种走法,选颜色字典序最小的走;如果有多条边的颜色字典序都是最小,则记录所有这些边的终点,走下一步时要考虑从所有这些点出发的边(具体实现就是边记录最小值边放入队列,然后在出队的时候判断)。

代码如下

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  5 #define Rep(i,n) for (int i = 0; i < (n); ++i)
  6 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
  7 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
  8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
  9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
 10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
 12
 13 #define pr(x) cout << #x << " = " << x << "  "
 14 #define prln(x) cout << #x << " = " << x << endl
 15
 16 #define LOWBIT(x) ((x)&(-x))
 17
 18 #define ALL(x) x.begin(),x.end()
 19 #define INS(x) inserter(x,x.begin())
 20 #define UNIQUE(x) x.erase(unique(x.begin(), x.end()), x.end())
 21 #define REMOVE(x, c) x.erase(remove(x.begin(), x.end(), c), x.end()); // 删去 x 中所有 c
 22 #define TOLOWER(x) transform(x.begin(), x.end(), x.begin(),::tolower);
 23 #define TOUPPER(x) transform(x.begin(), x.end(), x.begin(),::toupper);
 24
 25 #define ms0(a) memset(a,0,sizeof(a))
 26 #define msI(a) memset(a,0x7f,sizeof(a))
 27 #define msM(a) memset(a,-1,sizeof(a))
 28
 29 #define MP make_pair
 30 #define PB push_back
 31 #define ft first
 32 #define sd second
 33
 34 template<typename T1, typename T2>
 35 istream &operator>>(istream &in, pair<T1, T2> &p) {
 36     in >> p.first >> p.second;
 37     return in;
 38 }
 39
 40 template<typename T>
 41 istream &operator>>(istream &in, vector<T> &v) {
 42     for (auto &x: v)
 43         in >> x;
 44     return in;
 45 }
 46
 47 template<typename T>
 48 ostream &operator<<(ostream &out, vector<T> &v) {
 49     Rep(i, v.size()) out << v[i] << " \n"[i == v.size()];
 50     return out;
 51 }
 52
 53 template<typename T1, typename T2>
 54 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
 55     out << "[" << p.first << ", " << p.second << "]" << "\n";
 56     return out;
 57 }
 58
 59 inline int gc(){
 60     static const int BUF = 1e7;
 61     static char buf[BUF], *bg = buf + BUF, *ed = bg;
 62
 63     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
 64     return *bg++;
 65 }
 66
 67 inline int ri(){
 68     int x = 0, f = 1, c = gc();
 69     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
 70     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
 71     return x*f;
 72 }
 73
 74 template<class T>
 75 inline string toString(T x) {
 76     ostringstream sout;
 77     sout << x;
 78     return sout.str();
 79 }
 80
 81 inline int toInt(string s) {
 82     int v;
 83     istringstream sin(s);
 84     sin >> v;
 85     return v;
 86 }
 87
 88 //min <= aim <= max
 89 template<typename T>
 90 inline bool BETWEEN(const T aim, const T min, const T max) {
 91     return min <= aim && aim <= max;
 92 }
 93
 94 typedef long long LL;
 95 typedef unsigned long long uLL;
 96 typedef pair< double, double > PDD;
 97 typedef pair< int, int > PII;
 98 typedef pair< int, PII > PIPII;
 99 typedef pair< string, int > PSI;
100 typedef pair< int, PSI > PIPSI;
101 typedef set< int > SI;
102 typedef set< PII > SPII;
103 typedef vector< int > VI;
104 typedef vector< double > VD;
105 typedef vector< VI > VVI;
106 typedef vector< SI > VSI;
107 typedef vector< PII > VPII;
108 typedef map< int, int > MII;
109 typedef map< int, string > MIS;
110 typedef map< int, PII > MIPII;
111 typedef map< PII, int > MPIII;
112 typedef map< string, int > MSI;
113 typedef map< string, string > MSS;
114 typedef map< PII, string > MPIIS;
115 typedef map< PII, PII > MPIIPII;
116 typedef multimap< int, int > MMII;
117 typedef multimap< string, int > MMSI;
118 //typedef unordered_map< int, int > uMII;
119 typedef pair< LL, LL > PLL;
120 typedef vector< LL > VL;
121 typedef vector< VL > VVL;
122 typedef priority_queue< int > PQIMax;
123 typedef priority_queue< int, VI, greater< int > > PQIMin;
124 const double EPS = 1e-8;
125 const LL inf = 0x7fffffff;
126 const LL infLL = 0x7fffffffffffffffLL;
127 const LL mod = 1e9 + 7;
128 const int maxN = 1e5 + 7;
129 const LL ONE = 1;
130 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
131 const LL oddBits = 0x5555555555555555;
132
133 struct Edge{
134     int from, to, c;
135 };
136
137 int m, n, k;
138 vector< Edge > e;
139 VI v[maxN];
140 // path[i] 表示第 i 条边能取到的颜色的最小值
141 int d[maxN], path[maxN];
142 bool vis[maxN];
143
144 inline void addEdge(Edge &x) {
145     v[x.from].PB(e.size());
146     e.PB(x);
147     swap(x.from, x.to);
148     v[x.from].PB(e.size());
149     e.PB(x);
150 }
151
152 inline void bfs1() {
153     queue< int > Q;
154     d[n] = 0;
155     ms0(vis);
156     vis[n] = 1;
157     Q.push(n);
158
159     while(!Q.empty()) {
160         int tmp = Q.front(); Q.pop();
161
162         foreach(i, v[tmp]) {
163             Edge &x = e[*i];
164             if(vis[x.to]) continue;
165             vis[x.to] = 1;
166
167             d[x.to] = d[tmp] + 1;
168
169             if(x.to == 1) return;
170             Q.push(x.to);
171         }
172     }
173 }
174
175 inline void bfs2() {
176     queue< PII > Q;
177     // memset 是以8个bit为单位初始化的!!!
178     msI(path);
179     path[0] = 0;
180     ms0(vis);
181     Q.push(PII(1, 0));
182
183     while(!Q.empty()) {
184         // tmpv 为当前顶点, tmpc为到达当前顶点的边的颜色
185         int tmpv = Q.front().ft, tmpc = Q.front().sd; Q.pop();
186
187         if(path[k - d[tmpv]] < tmpc || vis[tmpv]) continue;
188         vis[tmpv] = 1; // 到达一个节点的路径可能有多条,不记录的话会被重复访问,复杂度指数上升
189
190         foreach(i, v[tmpv]) {
191             Edge &x = e[*i];
192             if(d[tmpv] - 1 != d[x.to] || d[x.to] == 0 && x.to != n) continue;
193             path[k - d[x.to]] = min(path[k - d[x.to]], x.c);
194
195             Q.push(PII(x.to, x.c));
196         }
197     }
198 }
199
200 int main(){
201     //freopen("MyOutput.txt","w",stdout);
202     //freopen("input.txt","r",stdin);
203     //INIT();
204     while(~scanf("%d%d", &n, &m)) {
205         e.clear();
206         For(i, 1, n) v[i].clear();
207
208         Rep(i, m) {
209             Edge t;
210             scanf("%d%d%d", &t.from, &t.to, &t.c);
211             addEdge(t);
212         }
213
214         bfs1();
215         k = d[1];
216
217         bfs2();
218
219         printf("%d\n", k);
220         For(i, 1, k) printf("%d%c", path[i], " \n"[i == k]);
221     }
222     return 0;
223 }

View Code

转载于:https://www.cnblogs.com/zaq19970105/p/11192258.html

UVA 1599 Ideal Path相关推荐

  1. UVA 12101 Prime Path (素数筛+BFS)

    题意:给一个四位数的素数,求通过几步变换(一次只能换一个位置的数,且变换过程中只能出现素数)变为目标四位数 分析:素数筛法+BFS,BFS时更换一个数字如果符合条件就加入队列 代码: #include ...

  2. 紫书《算法竞赛入门经典》

    紫书<算法竞赛入门经典>题目一览 第3章 数组和字符串(例题) UVA 272 TEX Quotes UVA 10082 WERTYU UVA 401 Palindromes UVA 34 ...

  3. 算法竞赛入门竞赛 入门经典 第六章 个人记录

    UVa 210 并行程序模拟(放弃 || 待补) 没看懂题意,但是有百度了一下duque 算是对duque有了一个大致的认识和了解 当然也有尝试. 本来想着去hdu找一些duque的题 结果 好像可以 ...

  4. 知识图谱开发实战案例剖析_我从剖析Web开发人员路线图中学到的知识

    知识图谱开发实战案例剖析 by Nicole Archambault 妮可·阿坎巴特(Nicole Archambault) 我从剖析Web开发人员路线图中学到的知识 (What I learned ...

  5. π-Algorithmist分类题目(2)

    原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(2) Set Theory U ...

  6. 《算法竞赛入门经典(第2版)》——学习记录

    前言:   这里主要记录本人在学习紫书过程中充分理解过的题目的AC代码,便于以后回顾时查找代码和思路,毕竟看别人的真的有点难懂.此外,本书甚至是本书之外的相关知识学习也可能在此留下记录.   作为一只 ...

  7. 【POJ3126 Prime Path】【POJ 3087 Shuffle'm Up】【UVA 11624 Fire!】【POJ 3984 迷宫问题】

    POJ3126Prime Path 给定两个四位素数a  b,要求把a变换到b 变换的过程要 每次变换出来的数都是一个 四位素数,而且当前这步的变换所得的素数  与  前一步得到的素数  只能有一个位 ...

  8. hdu 1599 find the mincost route(找无向图最小环)(floyd求最小环)

    ps(我到今天才知道Floyd的核心思想是动态规划==) hdu 1599 find the mincost route(找无向图最小环) 注意!这里写成   #define data 0x3f3f3 ...

  9. Uva(10048),最短路Floyd

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

最新文章

  1. tomcat 编译版本
  2. Ubuntu安装JDK配置环境变量
  3. Intel Realsense D435 如何通过图像识别出的比例点(x, y)获得实际点相对于摄像机原点的三维坐标(x, y, z)?
  4. 在利用计算机生成,计算机生成人像,从而使人脸的模糊变为现实
  5. 在HTML网页中嵌入脚本的方式
  6. 一个成功的BI项目实施需要注意哪些?
  7. 购买物联网卡应该注意哪些问题?
  8. python中返回上上级目录的命令
  9. 编译bib文件,报错repeated entry
  10. matlab画gds图,Matlab GDS流程.doc
  11. python+opencv实现相似图片的搜索
  12. Android大厂面试题系统分类从基础到困难(BATJ,蚂蚁金服,字节跳动,网易云,QQ音乐...)
  13. 用外业精灵完成施工前(光缆、电缆、拆迁)相关的踏勘-点位采集
  14. 论坛帖子(文章)点赞功能设计
  15. vue获取当前时间并时时刷新
  16. Cisco九位顶尖网络专家揭密
  17. LDC1612异常读数268435455
  18. [转]Go 的垃圾回收机制在实践中有哪些需要注意的地方?
  19. 宝宝吃母乳的一些的谣言辟谣
  20. web前端开发技术期末考试_Web前端开发技术期末试题与答案2

热门文章

  1. linux usb学习笔记
  2. Android input keyevent
  3. Moblin MID开发学习笔记 - application launcher安装过程
  4. problem b: 一年中的第几天_第九届蓝桥杯B组试题
  5. LeetCode 1765. 地图中的最高点(BFS)
  6. LeetCode 1624. 两个相同字符之间的最长子字符串
  7. LeetCode 1577. 数的平方等于两数乘积的方法数(双指针)
  8. LeetCode 1150. 检查一个数是否在数组中占绝大多数(二分查找)
  9. LeetCode 1306. 跳跃游戏 III(广度优先搜索BFS)
  10. php判断全是中文正则,php判断是否为中文正则表达式大全