Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input 输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。 (1
题解:
参考了大佬的代码。原来这题需要判重边。 经典dijkstra算法。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN =
1010;
const int INF =
0x3f3f3f3f;
int n,num;
int lowdis[MAXN];
int lowval[MAXN];
int visit[MAXN];
int m[MAXN][MAXN];
int cost[MAXN][MAXN];
void dijkstra(
int st)
{
int temp=
0;
for(
int i=
1;i<=n;i++)
{
lowdis[i]=m[st][i];
lowval[i]=cost[st][i];
}
memset(visit,
0,
sizeof(visit));
visit[st]=
1;
for(
int i=
1;i<n;i++)
{
int MIN=INF;
for(
int j=
0;j<=n;j++)
{
if(!visit[j]&&lowdis[j]<MIN)
{
temp=j;
MIN=lowdis[j];
}
}
visit[temp]=
1;
for(
int j=
1;j<=n;j++)
{
if(!visit[j]&&m[temp][j]<INF)
{
if(lowdis[j]>lowdis[temp]+m[temp][j])
{
lowdis[j]=lowdis[temp]+m[temp][j];
lowval[j]=lowval[temp]+cost[temp][j];
}
else if (lowdis[j]==lowdis[temp]+m[temp][j])
{
if(lowval[j]>lowval[temp]+cost[temp][j])
{
lowval[j]=lowval[temp]+cost[temp][j];
}
}
}
}
}
}
int main()
{
int st,ed;
int a,b,d,p;
while(
cin>>n>>num&&n+num)
{
memset(m,
0x3f,
sizeof(m));
memset(cost,
0x3f,
sizeof(cost));
for(
int i=
0;i<num;i++)
{
scanf(
"%d%d%d%d",&a,&b,&d,&p);
if(m[a][b]>d)
{
m[a][b]=m[b][a]=d;
cost[a][b] = cost[b][a] = p;
}
else if(m[a][b]==d)
{
if(cost[a][b]>p)
{
cost[a][b]=cost[b][a]=p;
}
}
}
scanf(
"%d%d",&st,&ed);
dijkstra(st);
printf(
"%d %d\n",lowdis[ed],lowval[ed]);
}
return 0;
}