题目描述
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入描述:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1
输出描述:
输出 一行有两个数, 最短距离及其花费。
示例1
输入
3 2
1 2 5 6
2 3 4 5
1 3
0 0
输出
9 11
题目解析:迪杰斯特拉计算单元最短路径,并且记录最小花费
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 1001
#define INF 0x3f3f3f3f
int n,m,adj[N][N],cost[N][N],visit[N],lowdis[N],lowcos[N];
void dijkstra(int s, int t)
{
memset(visit,0,sizeof(visit));
visit[s] = 1;
lowdis[s] = lowcos[s] = 0;
for(int i=1;i<=n;i++)
if(i != s)
{
lowdis[i] = adj[s][i];
lowcos[i] = cost[s][i];
}
int pos = s;
for(int i=1;i<=n;i++)
{
int mindis = INF;
for(int j=1;j<=n;j++)
if(!visit[j] && lowdis[j] < mindis)
{
mindis = lowdis[j];
pos = j;
}
if(mindis == INF)
break;
visit[pos] = 1;
for(int j=1;j<=n;j++)
if(adj[pos][j] != INF && cost[pos][j] != INF && (lowdis[j] >= lowdis[pos] + adj[pos][j]))
{
if((lowdis[j] == lowdis[pos] + adj[pos][j] && lowcos[j] > lowcos[pos] + cost[pos][j]) || (lowdis[j] > lowdis[pos] + adj[pos][j]))
lowcos[j] = lowcos[pos] + cost[pos][j];
lowdis[j] = lowdis[pos] + adj[pos][j];
}
}
printf("%d %d\n",lowdis[t],lowcos[t]);
}
int main()
{
while(scanf("%d %d",&n,&m) != EOF)
{
if(n == 0 && m == 0)
break;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
adj[i][j] = cost[i][j] = INF;
while(m--)
{
int a,b,d,p;
scanf("%d %d %d %d",&a,&b,&d,&p);
if(d < adj[a][b])
{
adj[a][b] = adj[b][a] = d;
cost[a][b] = cost[b][a] = p;
}
else if(d == adj[a][b] && p < cost[a][b])
cost[a][b] = cost[b][a] = p;
}
int s,t;
scanf("%d %d",&s,&t);
dijkstra(s,t);
}
return 0;
}