PAT 1087. All Roads Lead to Rome (30) Dijkstra题——多条件最短,最短路数量,途径点
2018-01-24 15:47
375 查看
/************************* 题意: 给出一个图,除了给出每个节点间的距离外 还告知了每个节点的happy值 让你求一个最短路径 要求路程最短。 如果路程相同,则让路上累加的happy值最大 happy值相等,则让路上经过的城市最少。 并给出相同最小路程的路径数量。 ************************/ /*********************** 解题思路: djkstra模板修改题 首先就是在dijksra中多加2种if判断,即判断h和c的 其次,求相同最小路径的数量。这个只要在更新时,若发现 d[j] == d[select] + d[select][j] 就给 roadnum[j] += roadnum[select] 即这个点的途径路径数量,要增加,增加的就是你更新的这个select 还有就是求过程中经过的点,这个不需要用vector去存,弄一个pre[]前指向数组即可 *************************/ /*********************** 笔记: *********************/ #include<iostream> #include<stdio.h> #include<string> #include<vector> #include<queue> #include<stdlib.h> #include<algorithm> #include<string.h> #include<stack> #include<map> #include<set> #include<unordered_map> using namespace std; #define M 300 #define INF 0x7ffffff string cityname[M]; int happy[M]; int dis[M][M]; map<string,int > getid; void dijk(int s, int e, int n){ int i, j, dmin, hmax, select, cmin; int d[M], vis[M], h[M], rnum[M],c[M],pre[M]; for(i = 0; i < n; i++){ d[i] = INF; vis[i] = 0; h[i] = -1; rnum[i] = 0; c[i] = INF; } d[s] = 0; h[s] = 0; rnum[s] = 1; c[s] = 1; pre[s] = -1; for(i = 0;i < n; i++){ dmin = INF; hmax = -1; cmin = INF; for(j = 0;j < n;j++){ if(vis[j]) continue; if(d[j] < dmin){ dmin = d[j]; hmax = h[j]; cmin = c[j]; select = j; }else if(d[j] == dmin){ if(h[j] > hmax){ hmax = h[j]; cmin = c[j]; select = j; }else if(h[j] == hmax){ if(c[j] < cmin){ cmin = c[j]; select = j; } } } } if(dmin ==INF) break; vis[select] = 1; for(j = 0;j < n; j++){ if(vis[j]) continue; if(d[select] + dis[select][j] < d[j]){ d[j] = d[select] + dis[select][j]; h[j] = h[select] + happy[j]; c[j] = c[select] + 1; pre[j] = select; rnum[j] = rnum[select]; }else if(d[select] + dis[select][j] == d[j]){ rnum[j] += rnum[select]; //统计different least road number if(h[select] + happy[j] > h[j]){ h[j] = h[select] + happy[j]; c[j] = c[select] +1; pre[j] = select; }else if(h[select] + happy[j] == h[j]){ if(c[select] + 1 < c[j]){ c[j] = c[select] + 1; pre[j] = select; } } } } } printf("%d %d %d %d\n",rnum[e], d[e], h[e], h[e]/(c[e] - 1)); int p = e; vector<string> ans; while(p != -1){ ans.push_back(cityname[p]); p = pre[p]; } for(i = ans.size() - 1;i >= 0;i--){ if(i != 0) cout<<ans[i]<<"->"; else cout<<ans[i]<<endl; } } int main(){ int i, n, m, d, j, end; string start, s, e; cin>>n>>m>>start; for(i=0;i<n;i++) for(j=0;j<n;j++) if(i!=j) dis[i][j] = INF; else dis[i][j] = 0; happy[0] = 0; cityname[0] = start; getid[start] = 0; for(i = 1; i < n ; i++){ cin>>cityname[i]>>happy[i]; if(cityname[i] == "ROM") end = i; getid[cityname[i]] = i; } while(m--){ cin>>s>>e>>d; dis[getid[s]][getid[e]] = d; dis[getid[e]][getid[s]] = d; } if(start == "ROM"){ printf("1 0 0 0\n"); cout<<"ROM"<<endl; } else dijk(0, end, n); return 0; }
相关文章推荐
- PAT甲题题解-1072. Gas Station (30)-dijkstra最短路
- PAT 1030. Travel Plan (30)(Dijkstra,最短路径的同时计算最小奥cost)
- PAT 1003. Emergency Dijkstra变形+求相等最短路的数量+特殊权重
- PAT 1030 Travel Plan dijkstra算法+双最短条件+保存最短路
- PAT甲题题解-1111. Online Map (30)-PAT甲级真题(模板题,两次Dijkstra,同时记下最短路径)
- 1072. Gas Station (30)【最短路dijkstra】——PAT (Advanced Level) Practise
- PAT (Advanced Level) 1030. Travel Plan (30) Dijkstra最短路径
- PAT (Advanced Level) 1072. Gas Station (30) Dijkstra最短路径+剪枝
- 1072. Gas Station (30)【最短路dijkstra】——PAT (Advanced Level) Practise
- PAT - 甲级 - 1072. Gas Station (30)(Dijkstra)
- PAT_1072. Gas Station(Dijkstra最短路)
- hdu3790 最短路径问题(spfa||dijkstra+两种限制条件)
- 1030. Travel Plan (30)-PAT甲级真题(Dijkstra + DFS,输出路径,边权)
- POJ2502 subway(dijkstra以最短时间代替最短路)
- 1087. All Roads Lead to Rome (30)-PAT甲级真题-Dijkstra + DFS
- Dijkstra求最短路的条数,并输出最短路径和最短路经过的点的最大和
- 1087. All Roads Lead to Rome (30)【最短路】——PAT (Advanced Level) Practise
- 最短路 dijkstra 权值非负的单源最短路径
- poj 3463 dijkstra变形(求最短路和次短路的数量)
- hdu 3790 最短路径问题(两个限制条件的最短路)