<题目链接>
题目大意:
给你一张图,有n个点,每个点都有需要缴的税,两个直接相连点之间的道路也有需要花费的费用。现在进行多次询问,给定起点和终点,输出给定起点和终点之间最少花费是多少,并且输出最少花费所走的路径,如果有多条路径花费最少,则输出字典序最小的那条。
解题分析:
输出最短路的路径问题,需要注意的是,题目要求输出的最短路径的字典序最小,所以我们在每次松弛的时候,都需要加上判断。如果有多个点的最短路相同,则用DFS求出它们之前走过的路径,并且进行比较,然后选字典序最小的那条。
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 #define clr(a,b) memset(a,b,sizeof(a)) 8 #define rep(i,s,t) for(int i=s;i<=t;i++) 9 #define INF 0x3f3f3f3f 10 const int M = 100+10; 11 int n,pos; 12 int path[M],mp[M][M],tax[M],vis[M],dis[M]; 13 char s1[110],s2[110]; 14 void dfs(int cur,char *s){ //找到这个点之前记录的路径s 15 if(cur == -1)return; 16 dfs(path[cur],s); 17 s[pos++]=cur+'0'; 18 } 19 bool Compare(int re,int now) { 20 pos=0;dfs(re,s1);s1[pos] = '0'; //将起点到re的最短路径储存 21 pos=0;dfs(now,s2);s2[pos++]=re+'0';s2[pos]=0; //将起点到u的最短路径储存 22 if(strcmp(s1,s2)>0)return true; //比较两个最短路之间的大小 23 return false; 24 } 25 void Dij(int st,int ed){ 26 rep(i,1,n){ 27 dis[i]=mp[st][i]+tax[i]; //将与st直接相连的点,边权与点权相加,视为经过i号城市的代价 28 if(i==st)continue; 29 if(dis[i]<INF)path[i]=st; //初始化path 30 } 31 rep(i,1,n){ 32 int mn=INF,cur; 33 rep(j,1,n) if(dis[j] < mn && !vis[j]) { //找到每一轮的起始节点 34 mn=dis[j],cur=j; 35 }vis[cur]=1; 36 rep(k,1,n) if(mp[cur][k] < INF){ 37 if(dis[k]>dis[cur]+mp[cur][k]+tax[k]){ //进行松弛,并且记录上一个节点 38 dis[k]=dis[cur]+mp[cur][k]+tax[k]; 39 path[k]=cur; 40 }else if(dis[k] == dis[cur]+mp[cur][k]+tax[k] && Compare(k,cur)){ 41 path[k]=cur; 42 }//若有多条最短路径(最短距离相同的时候)进行字典序大小判断,注意不能只比较一个节点,需要比较整个路径 43 } 44 } 45 } 46 void show(int cur,int st){ 47 if(cur == st){ cout<<cur; return ;} 48 show(path[cur],st); 49 cout<<"-->"<<cur; 50 } 51 int main(){ 52 while(~scanf("%d",&n),n){ 53 rep(i,1,n) rep(j,1,n){ 54 scanf("%d",&mp[i][j]); 55 if(mp[i][j]==-1)mp[i][j]=INF; 56 } 57 rep(i,1,n)scanf("%d",&tax[i]); 58 int u,v;while(scanf("%d%d",&u,&v)){ 59 if(u==-1 && v==-1)break; 60 clr(vis,0);clr(path,-1); 61 Dij(u,v); 62 cout<<"From "<<u<<" to "<<v<<" :"<<endl<<"Path: "; 63 show(v,u);puts(""); //从终点开始,利用递归,将逆序存储的路径正序输出 64 cout<<"Total cost : "<<dis[v]-tax[v]<<endl<<endl; //减去终点城市的城市税 65 } 66 } 67 }
2018-12-06