2022.2.13 练习 PAT 甲 1030 Travel Plan (原题链接)
题解一:
#include <bits/stdc++.h> using namespace std; const int MAX_NUM=510; const int INF=0x3fffffff; int n,m,s,D; int d[MAX_NUM];//起点到各点的最短路径长度 int visit[MAX_NUM]={0};//标记是否已经访问 int G[MAX_NUM][MAX_NUM];//邻接矩阵,存放距离 int cost[MAX_NUM][MAX_NUM];//存放两点间的花费 int min_cost=INF;//最少花费 vector<int> pre[MAX_NUM];//每个结点所能产生的最短路径的前驱结点 void Dijkstra(int s) { fill(d,d+MAX_NUM,INF); d[s]=0; for(int i=0;i<n;i++) { int u=-1,MIN=INF; for(int j=0;j<n;j++) { if(visit[j]==0 && d[j]<MIN) { u=j; MIN=d[j]; } } if(u==-1) return; visit[u]=1; //cout<<u<<" : "; for(int v=0;v<n;v++) { if(visit[v]==0 && G[u][v]!=INF) { //cout<<v<<endl; if( d[u]+G[u][v]<d[v] ) { d[v]=d[u]+G[u][v]; pre[v].clear(); pre[v].push_back(u); } else if ( d[u]+G[u][v]==d[v] ) { pre[v].push_back(u); } } } } } vector<int> path,tmp_path; void DFS(int v) { if(v==s)//叶子结点等于起点 { tmp_path.push_back(v); int cost_tmp=0; for(int i=tmp_path.size()-1;i>0;i--) { int id=tmp_path[i]; int id_next=tmp_path[i-1]; cost_tmp+=cost[id][id_next]; } if(cost_tmp<min_cost) { min_cost=cost_tmp; path=tmp_path; } tmp_path.pop_back(); return ; } tmp_path.push_back(v); for(int i=0;i<pre[v].size();i++) { DFS(pre[v][i]); } tmp_path.pop_back(); } int main() { std::ios::sync_with_stdio(false); cin>>n>>m>>s>>D; fill(G[0],G[0]+MAX_NUM*MAX_NUM,INF);//初始化邻接矩阵 fill(cost[0],cost[0]+MAX_NUM*MAX_NUM,INF);//初始化邻接矩阵 while(m--) { int c1,c2,dis,c; cin>>c1>>c2>>dis>>c; G[c1][c2]=G[c2][c1]=dis; cost[c1][c2]=cost[c2][c1]=c; } Dijkstra(s); DFS(D); for(int i=path.size()-1;i>=0;i--) { cout<<path[i]<<" "; } cout<<d[D]<<" "<<min_cost; return 0; }
题解二:
#include <bits/stdc++.h> using namespace std; const int MAX_NUM=510; const int INF=0x3fffffff; int n,m,s,D; int d[MAX_NUM];//起点到各点的最短路径长度 int visit[MAX_NUM]={0};//标记是否已经访问 int G[MAX_NUM][MAX_NUM];//邻接矩阵,存放距离 int cost[MAX_NUM][MAX_NUM];//存放两点间的花费 int cc[MAX_NUM];//从起点到某一点的最少花费 int pre[MAX_NUM];//从起点到抹一点的最短路径上该点的前一个顶点 int min_cost=INF;//最少花费 void Dijkstra(int s) { fill(d,d+MAX_NUM,INF); fill(cc,cc+MAX_NUM,INF); d[s]=0; cc[s]=0; for(int i=0;i<n;i++) { pre[i]=i; } for(int i=0;i<n;i++) { int u=-1,MIN=INF; for(int j=0;j<n;j++) { if(visit[j]==0 && d[j]<MIN) { u=j; MIN=d[j]; } } if(u==-1) return; visit[u]=1; for(int v=0;v<n;v++) { if(visit[v]==0 && G[u][v]!=INF) { if( d[u]+G[u][v]<d[v] ) { d[v]=d[u]+G[u][v]; pre[v]=u; cc[v]=cc[u]+cost[u][v]; } else if ( d[u]+G[u][v]==d[v] && cc[v]>cc[u]+cost[u][v]) { cc[v]=cc[u]+cost[u][v]; pre[v]=u; } } } } } void DFS(int s,int v) { if(v==s) { cout<<s<<" "; return ; } DFS(s,pre[v]); cout<<v<<" "; } int main() { std::ios::sync_with_stdio(false); cin>>n>>m>>s>>D; fill(G[0],G[0]+MAX_NUM*MAX_NUM,INF);//初始化邻接矩阵 fill(cost[0],cost[0]+MAX_NUM*MAX_NUM,INF);//初始化邻接矩阵 while(m--) { int c1,c2,dis,c; cin>>c1>>c2>>dis>>c; G[c1][c2]=G[c2][c1]=dis; cost[c1][c2]=cost[c2][c1]=c; } Dijkstra(s); DFS(s,D); cout<<d[D]<<" "<<cc[D]; return 0; }