HDU 1385 Minimum Transport Cost 【最短路 + 最小字典序路径输出】
2018-01-26 16:42
621 查看
传送门
// 题意: 给定一个矩阵表示点与边的关系, 有向边, 并且每个点有税收, 起点和终点不收税. 然后给出一系列的询问, st 到 ed的最短路是多少, 并且要输出该路径, 特别注意就是如果有同样的答案的最短路, 输出字典序最小的那条.
// 思路: 首先还是最短路, 那么注意几个问题, 一是在结构体中加string name, 不能单纯的以前面那个点来排, 因为有可能小的在前面, 所以我们应该吧前面所选过的全部先存下来, 去总的最小, 而不是前面的那个最小. 其次就是如果有相等距离的, 我们应该比较下它上次取该值的字典序和当前的进行一次比较, 如果更小依旧要进行更新. 具体细节请看代码.
几个坑点 :
1:
6
0 100 100 100 1 1
100 100 100 1 100 100
100 100 100 1 100 100
100 100 100 100 100 100
100 100 1 100 100 100
100 1 100 100 100 100
0 0 0 0 0 0
1 4
-1 -1
ans : 1->5->3->4
2:
3
0 2 4
-1 0 1
-1 -1 0
1 1 1
1 3
1 1
-1 -1
ans: 1 -> 2 -> 3
3: 自己到自己输出 st, 而不是st -> st.
这几个都能过就没有问题了.
AC Code
// 题意: 给定一个矩阵表示点与边的关系, 有向边, 并且每个点有税收, 起点和终点不收税. 然后给出一系列的询问, st 到 ed的最短路是多少, 并且要输出该路径, 特别注意就是如果有同样的答案的最短路, 输出字典序最小的那条.
// 思路: 首先还是最短路, 那么注意几个问题, 一是在结构体中加string name, 不能单纯的以前面那个点来排, 因为有可能小的在前面, 所以我们应该吧前面所选过的全部先存下来, 去总的最小, 而不是前面的那个最小. 其次就是如果有相等距离的, 我们应该比较下它上次取该值的字典序和当前的进行一次比较, 如果更小依旧要进行更新. 具体细节请看代码.
几个坑点 :
1:
6
0 100 100 100 1 1
100 100 100 1 100 100
100 100 100 1 100 100
100 100 100 100 100 100
100 100 1 100 100 100
100 1 100 100 100 100
0 0 0 0 0 0
1 4
-1 -1
ans : 1->5->3->4
2:
3
0 2 4
-1 0 1
-1 -1 0
1 1 1
1 3
1 1
-1 -1
ans: 1 -> 2 -> 3
3: 自己到自己输出 st, 而不是st -> st.
这几个都能过就没有问题了.
AC Code
const int inf = 0x3f3f3f3f; //用这个可以直接mem const int maxn = 50+5; int cas=1; int cnt, head[maxn]; int g[maxn][maxn]; struct node { int to, next, w; string name; bool operator < (const node& a) const { if (w != a.w) return w > a.w; return name > a.name; // 保证总的最小而不单单是前面那个最小. } } e[maxn*maxn]; void add(int u, int v,int w) { e[cnt] = (node){v,head[u],w, ""}; head[u] = cnt++; } void init() { cnt = 0; memset(head, -1, sizeof(head)); } bool vis[maxn]; int dis[maxn], a[maxn], pre[maxn]; void dij(int st,int ed) { priority_queue<node> q; Fill(dis,inf); Fill(vis,0); string s[maxn]; dis[st] = 0; string tmp ; tmp += st + '0'; q.push((node){st, 0, 0, tmp}); while (!q.empty()) { node u = q.top(); q.pop(); if (u.to == ed) break; if(vis[u.to]) continue; vis[u.to] = 1; string tt = u.name; for (int i = head[u.to]; ~i; i = e[i].next) { node k = e[i]; int w = dis[u.to] + k.w; if (k.to != ed) w += a[k.to]; string tmp = (tt += k.to +'0'); // 这个是用来比较相等的情况的. if (dis[k.to] > w || (dis[k.to] == w && tmp < s[k.to])) { dis[k.to] = w; s[k.to] = tmp; pre[k.to] = u.to; q.push((node){k.to, 0, dis[k.to], s[k.to]}); } tt = u.name; } } } int ans[maxn]; void solve() { int n; while(~scanf("%d", &n) && n) { init(); for (int i = 1 ; i <= n ; i ++) { for (int j = 1 ; j <= n ; j ++) { scanf("%d", &g[i][j]); if (g[i][j] != -1 && i != j) { add(i, j, g[i][j]); } } } for (int i = 1 ; i <= n ; i ++) scanf("%d", &a[i]); int st, ed; while(1) { scanf("%d%d", &st, &ed); if (st == -1 && ed == -1) break; Fill(pre, -1); pre[st] = st; dij(st, ed); Fill(ans ,0); printf("From %d to %d :\n", st, ed); if (st == ed) printf("Path: %d\n", st); else { printf("Path: %d-->", st); int tt = pre[ed]; int k = 0; while(tt != st) { ans[++k] = tt; tt = pre[tt]; } for (int i = k ; i >= 1 ; i --) { printf("%d-->", ans[i]); } printf("%d\n", ed); } printf("Total cost : %d\n\n", dis[ed]); } } }
相关文章推荐
- Minimum Transport Cost hdu 点权和边权的最短路+输出字典序最小的路径
- HDU 1385 Minimum Transport Cost (最短路,并输出路径)
- hdu 1385(zoj 1456)Minimum Transport Cost(最短路,输出路径,Floyd实现)
- HDU1385 Minimum Transport Cost(最短路输出路径)
- hdu 1385 Minimum Transport Cost (最小字典序最短路径)
- hdu 1385 Minimum Transport Cost(最短路+输出路径)
- hdu 1385 Minimum Transport Cost 最短路加路径输出
- hdu 1385 Minimum Transport Cost(最短路 + 字典序最小路径)
- HDU 1385 Minimum Transport Cost(Floyd+打印字典序最小路径)
- HDU 1385 Minimum Transport Cost(最短路Floyd+标记路径)
- HDU 1385 Minimum Transport Cost(Floyd+路径输出)
- hdu 1385 Minimum Transport Cost(判断字典序+输出路径)
- HDU 1385 Minimum Transport Cost(最短路,打印字典序路径)
- Minimum Transport Cost hdu 1385(最短路 + 路径保存 + stack)
- hdu 1385 Minimum Transport Cost(输出最短路径)
- HDU 1385 Minimum Transport Cost (Floyd算法 + 路径输出)
- HDU 1385 Minimum Transport Cost(Floyd 最短路 打印路径)
- HDOJ 题目 1385 Minimum Transport Cost(最短路输出路径)
- HDOJ 题目1385 Minimum Transport Cost(最短路,输出路径)
- hdu 1385 Minimum Transport Cost(最短路,floyd打印字典序路径)