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<n<=1000, 0<m<100000, s != t)
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
Sample Output
9 11
Dijkstra 算法
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX 9999999
using namespace std;
int m,n;
int s,e;
int a[1001][1001],v[100001],b[100001];
int a1[1001][1001];
int v1[100001];
void Dijkstra()
{
int i,j,k;
memset(b,0,sizeof(b));
for(i=0;i<=n;i++)
v[i]=MAX;
for(i=1;i<=n;i++)
{
v[i]=a[s][i];
v1[i]=a1[s][i];
}
v[s]=0;
b[s]=1;
v1[s]=0;
int min= MAX;
for(i=1;i<n;i++)
{
min=MAX;
for(j=1;j<=n;j++)
{
if(!b[j]&&min>v[j])
{
min=v[j];
k=j;
}
}
b[k]=1;
for(j=1;j<=n;j++)
{
if(!b[j]&&v[j]>v[k]+a[k][j])
{
v[j]=v[k]+a[k][j];
v1[j]=v1[k]+a1[k][j];
}
else if(!b[j]&&v[j]==v[k]+a[k][j])
{
if(v1[j]>v1[k]+a1[k][j])
{
v1[j]=v1[k]+a1[k][j];
}
}
}
}
printf("%d %d\n",v[e],v1[e]);
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)&&(m||n))
{
memset(a1,0,sizeof(a1));
for(i=0;i<=n;i++)
{
for(j=0;j<=n;j++)
{
a[i][j]=a[j][i]=MAX;
}
a[i][i]=0;
}
int x,y,d,p;
for(i=0;i<m;i++)
{
scanf("%d%d%d%d",&x,&y,&d,&p);
if(a[x][y]>d)
{
a[x][y]=a[y][x]=d;
a1[x][y]=a1[y][x]=p;
}
}
scanf("%d%d",&s,&e);
Dijkstra();
}
}
Bellman 算法
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int inf = 100005;
int n,m,a,b,d,p,num=0;
int dis[inf],money[inf];
struct node
{
int u,v,w,money;
} q[100005];
void Bellman_Ford (int s,int t)
{
for (int i = 0; i <= n; i++)
{
dis[i] = inf;
money[i] = 0;
}
dis[s] = 0;
money[s] = 0;
int flag = 0;
for (int i = 0; i < n; i++)
{
flag = 0;
for (int j = 0 ; j < num; j++)
{
if (dis[q[j].v] > dis[q[j].u] +q[j].w)
{
flag = 1;
dis[q[j].v] = dis[q[j].u] + q[j].w;
money[q[j].v] = money[q[j].u] + q[j].money;
}
else if (dis[q[j].v] == dis[q[j].u] +q[j].w)
{
if (money[q[j].v] > money[q[j].u] + q[j].money)
money[q[j].v] = money[q[j].u] + q[j].money;
}
}
if (flag == 0)
break;
}
printf ("%d %d\n",dis[t],money[t]);
}
int main ()
{
while (~scanf ("%d%d",&n,&m)&&n&&m)
{
num = 0;
for (int i = 0 ; i < m; i++)
{
scanf ("%d%d%d%d",&a,&b,&d,&p);
q[num].u = a,q[num].v = b,q[num].w = d,q[num++].money = p;
q[num].u = b,q[num].v = a,q[num].w = d,q[num++].money = p;
}
int s,t;
scanf ("%d%d",&s,&t);
Bellman_Ford (s,t);
}
return 0;
}