数据结构实验之图论七:驴友计划
做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。
Input
连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。
Output
在同一行中输出路径长度和收费总额,数据间用空格间隔。
Sample Input
1
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
Sample Output
3 40
解法一:(Floyd算法)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 510
#define MAX 0x3f3f3f3f
int map[N][N];
int cost[N][N];
int n, m, s, d;
void floyd(int x, int y)
{
int i, j, k;
for(k=0; k<n; k++)
{
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if((map[i][j]>map[i][k]+map[k][j])||(map[i][j]==map[i][k]+map[k][j] && cost[i][j]>cost[i][k]+cost[k][j]))
{
map[i][j]=map[i][k]+map[k][j];
cost[i][j]=cost[i][k]+cost[k][j];
}
}
}
}
printf("%d %d\n", map[x][y], cost[x][y]);
return;
}
int main()
{
int i, t, j;
int a, b, c, z;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d%d", &n, &m, &s, &d);
for(i=0; i<=n; i++)
{
for(j=0; j<=n; j++)
{
map[i][j] = MAX;
cost[i][j] = MAX;
}
}
for(i=0; i<m; i++)
{
scanf("%d%d%d%d", &a, &b, &c, &z);
if(map[a][b] > c)
{
map[a][b] = map[b][a] = c;
cost[a][b] = cost[b][a] = z;
}
}
floyd(s, d);
}
return 0;
}
解法二:(Dijkstra算法)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 510
#define MAX 0x3f3f3f3f
int map[N][N];
int cost[N][N];
int n, m, s, d;
int dis1[N];
int dis2[N];
int visit[N];
void dijkstra(int x, int y)
{
int i, j, k;
for(i=0; i<=n; i++)
{
visit[i] = 0;
dis1[i] = map[x][i];
dis2[i] = cost[x][i];
}
dis1[x] = 0;
dis2[x] = 0;
visit[x] = 1;
for(i=0; i<n; i++)
{
int min1 = MAX;
int min2 = MAX;
for(j=0; j<n; j++)
{
if(visit[j]==0 && ((dis1[j]<min1) || (dis1[j]==min1 && dis2[j]<min2)))
{
k = j;
min1 = dis1[j];
min2 = dis2[j];
}
}
visit[k] = 1;
for(j=0; j<n; j++)
{
if(visit[j]==0 && (dis1[j] > dis1[k]+map[k][j] || (dis1[k]+map[k][j]==dis1[j] && dis2[j]>dis2[k]+cost[k][j])))
{
dis1[j] = dis1[k] + map[k][j];
dis2[j] = dis2[k] + cost[k][j];
}
}
}
printf("%d %d\n", dis1[y], dis2[y]);
return;
}
int main()
{
int i, t, j;
int a, b, c, z;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d%d", &n, &m, &s, &d);
for(i=0; i<=n; i++)
{
for(j=0; j<=n; j++)
{
map[i][j] = MAX;
cost[i][j] = MAX;
}
}
for(i=0; i<m; i++)
{
scanf("%d%d%d%d", &a, &b, &c, &z);
if(map[a][b] > c)
{
map[a][b] = map[b][a] = c;
cost[a][b] = cost[b][a] = z;
}
}
dijkstra(s, d);
}
return 0;
}
解法三:(SPFA算法_bfs)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 510
#define MAX 0x3f3f3f3f
int map[N][N];
int cost[N][N];
int quene[N];
int n, m, s, d;
int dis1[N];
int dis2[N];
int visit[N];
void spfa_bfs(int x, int y)
{
int i, j, k;
for(i=0; i<=n; i++)
{
visit[i] = 0;
dis1[i] = MAX;
dis2[i] = MAX;
}
dis1[x] = 0;
dis2[x] = 0;
visit[x] = 1;
int top = 0;
int under = 0;
quene[top++] = x;
while(under<top)
{
int u = quene[under++];
visit[u] = 1;
for(i=0; i<n; i++)
{
if(dis1[i]>dis1[u]+map[u][i] || (dis1[i]==dis1[u]+map[u][i] && dis2[i]>dis2[u]+cost[u][i]))
{
dis1[i] = dis1[u] + map[u][i];
dis2[i] = dis2[u] + cost[u][i];
if(visit[i]==0)
{
quene[top++] = i;
visit[i] = 1;
}
}
}
}
printf("%d %d\n", dis1[y], dis2[y]);
return;
}
int main()
{
int i, t, j;
int a, b, c, z;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d%d", &n, &m, &s, &d);
for(i=0; i<=n; i++)
{
for(j=0; j<=n; j++)
{
map[i][j] = MAX;
cost[i][j] = MAX;
}
}
for(i=0; i<m; i++)
{
scanf("%d%d%d%d", &a, &b, &c, &z);
if(map[a][b] > c)
{
map[a][b] = map[b][a] = c;
cost[a][b] = cost[b][a] = z;
}
}
spfa_bfs(s, d);
}
return 0;
}
解法四:(SPFA_dfs算法)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 510
#define MAX 0x3f3f3f3f
int map[N][N];
int cost[N][N];
int quene[N];
int n, m, s, d;
int dis1[N];
int dis2[N];
int visit[N];
int spfa_dfs(int x)
{
int i, j, k;
visit[x] = 1;
for(i=0; i<n; i++)
{
if(dis1[i]>dis1[x]+map[x][i] || (dis1[i]==dis1[x]+map[x][i] && dis2[i]>dis2[x]+cost[x][i]))
{
dis1[i] = dis1[x] + map[x][i];
dis2[i] = dis2[x] + cost[x][i];
if(visit[i]==0)
{
if(spfa_dfs(i))
return 1;
}
else
return 1;
}
}
visit[x] = 0;
return 0;
}
int main()
{
int i, t, j;
int a, b, c, z;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d%d", &n, &m, &s, &d);
for(i=0; i<=n; i++)
{
for(j=0; j<=n; j++)
{
map[i][j] = MAX;
cost[i][j] = MAX;
}
}
for(i=0; i<m; i++)
{
scanf("%d%d%d%d", &a, &b, &c, &z);
if(map[a][b] > c)
{
map[a][b] = map[b][a] = c;
cost[a][b] = cost[b][a] = z;
}
}
for(i=0; i<=n; i++)
{
visit[i] = 0;
dis1[i] = MAX;
dis2[i] = MAX;
}
dis1[s] = 0;
dis2[s] = 0;
int k = spfa_dfs(s);
printf("%d %d\n", dis1[d], dis2[d]);
}
return 0;
}
解法五:(Bellman_Ford)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 600
#define MAX 0x3f3f3f3f
struct node
{
int u;
int v;
int s;
int w;
} map[N], p;
int n, m, z, q;
int top;
int dis1[N];
int dis2[N];
void Bellman_Ford(int x, int y)
{
int i, j, flag;
for(i=1; i<=n; i++)
{
dis1[i] = MAX;
dis2[i] = MAX;
}
dis1[x] = 0;
dis2[x] = 0;
for(i=1; i<=n-1; i++)
{
int flag = 0;
for(j=1; j<top; j++)
{
if((dis1[map[j].v] > dis1[map[j].u]+map[j].s)||(dis1[map[j].v]==dis1[map[j].u]+map[j].s && dis2[map[j].v]>dis2[map[j].u]+map[j].w))
{
dis1[map[j].v] = dis1[map[j].u] + map[j].s;
dis2[map[j].v] = dis2[map[j].u] + map[j].w;
flag = 1;
}
}
if(flag==0)
break;
}
printf("%d %d\n", dis1[y], dis2[y]);
}
int main()
{
int t, i;
int a, b, c, d;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d%d", &n, &m, &z, &q);
for(i=0; i<N; i++)
{
map[i].s = MAX;
map[i].w = MAX;
}
top = 0;
while(m--)
{
scanf("%d%d%d%d", &a, &b, &c, &d);
p.u = a;
p.v = b;
p.s = c;
p.w = d;
map[top++] = p;
p.u = b;
p.v = a;
p.s = c;
p.w = d;
map[top++] = p;
}
Bellman_Ford(z, q);
}
}