PAT_A1030
PAT甲级1030.
目录
A1030
题目
样例
输入:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输出:
0 2 3 3 40
思路和坑点
两个优化参数的最短路径问题,而且问题的路径答案唯一,直接使用一次Dijkstra算法,同时对两个变量进行优化即可。
AC代码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 505
#define INF 0x3fffffff
int n,m,s,d; //参数
int dis[MAXN],cost[MAXN],pre[MAXN]; //最短距离数组,最小花费数组,路径前驱数组
int G[MAXN][MAXN]; //图
int C[MAXN][MAXN]; //花费
bool vis[MAXN]={false}; //访问标记
void D(){ //两个参数的Dijkstra算法模板
fill(dis,dis+MAXN,INF);
fill(cost,cost+MAXN,INF);
dis[s]=cost[s]=0;
for(int i=0;i<n;i++){
int u=-1,MIN=INF;
for(int j=0;j<n;j++){
if(vis[j]==false&&dis[j]<MIN){
u=j;
MIN=dis[j];
}
}
if(u==-1) return;
vis[u]=true;
for(int v=0;v<n;v++){
if(vis[v]==false&&G[u][v]!=INF){
if(dis[u]+G[u][v]<dis[v]){
dis[v]=dis[u]+G[u][v];
cost[v]=cost[u]+C[u][v];
pre[v]=u;
}
else if(dis[u]+G[u][v]==dis[v]&&cost[u]+C[u][v]<cost[v]){
cost[v]=cost[u]+C[u][v];
pre[v]=u;
}
}
}
}
}
int main(void){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
fill(G[0],G[0]+MAXN*MAXN,INF); //初始化
fill(C[0],C[0]+MAXN*MAXN,INF);
fill(pre,pre+MAXN,-1);
scanf("%d%d%d%d",&n,&m,&s,&d); //读入数据
for(int i=0;i<m;i++){
int a,b,d,c;
scanf("%d%d",&a,&b);
scanf("%d%d",&G[a][b],&C[a][b]);
G[b][a]=G[a][b]; C[b][a]=C[a][b];
}
D();
vector<int> out; //保存并输出路径
out.push_back(cost[d]); out.push_back(dis[d]); //最短距离和最小花费一并放入输出结果的数组中
while(d!=-1){
out.push_back(d);
d=pre[d];
}
for(int i=out.size()-1;i>=0;i--){
if(i!=out.size()-1) putchar(' ');
printf("%d",out[i]);
}
return 0;
}