您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: