题意:一个国家有N个城市,这些城市之间有一条路或是没有路。现在需要从一个城市往另外一个城市运送货物。运输费用由两部分组成:路上的费用和经过的城市收的税。现在要求某次运输的最少花费。
思路:求多源最短路径,在计算最小费用时加个税就好了。还有就是如果存在多条最短路径,要输出字典序最小的一条。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 1010;
const int INF = 0x3f3f3f3f;
int N;
int G[MAXN][MAXN];
int nxt[MAXN][MAXN];
int tax[MAXN];
void Flyod()
{
for(int k=0; k<N; k++){
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
if(G[i][k]<INF && G[k][j]<INF && G[i][j] > G[i][k]+tax[k]+G[k][j]){
G[i][j] = G[i][k]+tax[k]+G[k][j];
nxt[i][j] = nxt[i][k];
}
else if(G[i][j] == G[i][k]+tax[k]+G[k][j]){
nxt[i][j] = min(nxt[i][j], nxt[i][k]);
}
}
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
while(scanf("%d", &N) == 1 && N){
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
scanf("%d", &G[i][j]);
if(G[i][j] == -1) G[i][j] = INF;
nxt[i][j] = j;
}
}
for(int i=0; i<N; i++){
scanf("%d", &tax[i]);
}
Flyod();
int c,d;
bool first = true;
while(scanf("%d%d", &c, &d)==2 && c!=-1 && d!=-1){
printf("From %d to %d :\nPath: %d", c, d, c);
c--; d--;
int p = c;
while(p != d){
printf("-->%d", nxt[p][d]+1);
p = nxt[p][d];
}
printf("\nTotal cost : %d\n\n", G[c][d]);
}
}
return 0;
}