数据结构实验之图论七:驴友计划
Time Limit: 1000MS Memory limit: 65536K
题目描述
做为一个资深驴友,小新有一张珍藏的自驾游线路图,图上详细的标注了全国各个城市之间的高速公路距离和公路收费情况,现在请你编写一个程序,找出一条出发地到目的地之间的最短路径,如果有多条路径最短,则输出过路费最少的一条路径。
输入
连续T组数据输入,每组输入数据的第一行给出四个正整数N,M,s,d,其中N(2 <= N <= 500)是城市数目,城市编号从0~N-1,M是城市间高速公路的条数,s是出发地的城市编号,d是目的地的城市编号;随后M行,每行给出一条高速公路的信息,表示城市1、城市2、高速公路长度、收费额,中间以空格间隔,数字均为整数且不超过500,输入数据均保证有解。
输出
在同一行中输出路径长度和收费总额,数据间用空格间隔。
示例输入
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
示例输出
3 40
提示
来源
xam
示例程序
解法一:(Floyd算法)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Max 100000000
int main()
{
int n,m,i,j,k,x,y,t,p,s,e,l;
int code[510][510],dis[510][510];
scanf("%d",&l);
while(l--)
{
scanf("%d %d %d %d",&n,&m,&s,&e);
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
if(i==j)
{
code[i][j]=0;
dis[i][j]=0;
}
else
{
code[i][j]=Max;
dis[i][j]=Max;
}
for(i=1;i<=m;i++)
{
scanf("%d %d %d %d",&x,&y,&t,&p);
if(code[x][y]>t)
{
code[x][y]=t;
code[y][x]=t;
dis[x][y]=p;
dis[y][x]=p;
}
}
for(i=s;i<=e;i++)
{
for(j=s;j<=e;j++)
{
for(k=s;k<=e;k++)
{
if(code[j][k]>(code[i][j]+code[i][k])||(code[j][k]==(code[i][j]+code[i][k])&&dis[j][k]>(dis[i][j]+dis[i][k])))
{
code[j][k]=code[i][j]+code[i][k];
dis[j][k]=dis[i][j]+dis[i][k];
}
}
}
}
printf("%d %d\n",code[s][e],dis[s][e]);
}
return 0;
}
解法二:(Dijkstra算法)
#include<stdio.h>
#include<string.h>
#define INF 65535
struct node
{
int a,b;
} map[1005][1005];;
int p[10010],final[1010],d[1000],d1[1010],s;
int n,m;
void Dijkstra()
{
int v,w,k,min,mi;
for(v=1;v<=n;v++)
{
final[v]=0;
d[v]=map[s][v].a;
d1[v]=map[s][v].b;
p[v]=0;
}
d[s]=0;
d1[s]=0;
final[s]=1;
for(v=2;v<=n;v++)
{
min=INF;
mi=INF;
for(w=1;w<=n;w++)
{
if(!final[w]&&(d[w]<min)||(d[w]==min&&mi>d1[w]))
{
k=w;
min=d[w];
mi=d1[w];
}
}
final[k]=1;
for(w=1;w<=n;w++)
{
if(!final[w]&&(min+map[k][w].a<d[w]||(min+map[k][w].a==d[w]&&mi+map[k][w].b<d1[w])))
{
d[w]=min+map[k][w].a;
d1[w]=mi+map[k][w].b;
p[w]=k;
}
}
}
}
int main()
{
int i,j,k,l1,l2,l3,l4,x,t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d %d",&n,&m,&s,&x);
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
if(i==j)
{
map[i][j].a=0;
map[i][j].b=0;
}
else
{
map[i][j].a=INF;
map[i][j].b=INF;
}
for(i=0;i<m;i++)
{
scanf("%d %d %d %d",&l1,&l2,&l3,&l4);
map[l1][l2].a=l3;
map[l2][l1].a=l3;
map[l1][l2].b=l4;
map[l2][l1].b=l4;
}
Dijkstra();
printf("%d %d\n",d[x],d1[x]);
}
}
解法三:(SPFA算法_bfs)
#include<stdio.h>
#include<string.h>
#include<queue>
#include<climits>
using namespace std;
long long INF=LONG_LONG_MAX;
long long dis[600],dis1[600];
int vis[600];
struct node
{
int to;
int w,w1;
};
int n,m,s,t,x;
vector<struct node>map[600];
void SPFA()
{
queue<int>a;
for(int i=0;i<n;i++)
{
dis[i]=INF;
dis1[i]=INF;
}
memset(vis,0,sizeof(vis));
dis[s]=0;
dis1[s]=0;
vis[s]=1;
a.push(s);
while(!a.empty())
{
int u=a.front();
a.pop();
vis[u]=0;
int tt=map[u].size();
for(int i=0;i<tt;i++)
{
int to=map[u][i].to;
if(dis[u]<INF&&(dis[to]>dis[u]+map[u][i].w||(dis[to]==dis[u]+map[u][i].w)&&dis1[to]>dis1[u]+map[u][i].w))
{
dis[to]=dis[u]+map[u][i].w;
dis1[to]=dis1[u]+map[u][i].w1;
if(!vis[to])
{
a.push(to);
vis[to]=1;
}
}
}
}
}
int main()
{
int T,u,v,w,w1;
struct node temp;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d",&n,&m,&s,&t);
for(int i=0;i<n;i++)
map[i].clear();
for(int i=1;i<=m;i++)
{
scanf("%d %d %d %d",&u,&v,&w,&w1);
temp.to=v;
temp.w=w;
temp.w1=w1;
map[u].push_back(temp);
temp.to=u;
map[v].push_back(temp);
}
SPFA();
printf("%lld %lld\n",dis[t],dis1[t]);
}
}
解法四:(SPFA_dfs算法)
#include<stdio.h>
#include<string.h>
int INF=65535;
int d[600],d1[600];
int vis[600],head[600];
struct node
{
int v;
int w,w1;
int next;
}st[100000];
int n,m,s,t,x,l;
void add(int u,int v,int w,int w1)
{
st[l].v=v;
st[l].w=w;
st[l].w1=w1;
st[l].next=head[u];
head[u]=l++;
}
int spfa_dfs(int u)
{
vis[u]=1;
for(int k=head[u]; k!=-1; k=st[k].next)
{
int v=st[k].v,w=st[k].w,w1=st[k].w1;
if( d[u]+w <d[v]||(d[u]+w ==d[v]&&d1[u]+w1 <d1[v] ))
{
d[v]=d[u]+w;
d1[v]=d1[u]+w1;
if(!vis[v])
{
if(spfa_dfs(v))
return 1;
}
else
return 1;
}
}
vis[u]=0;
return 0;
}
int main()
{
int T,u,v,w,w1,k,i;
scanf("%d",&T);
while(T--)
{
l=0;
scanf("%d %d %d %d",&n,&m,&s,&t);
for(i=0;i<=n;i++)
{
d[i]=INF;
d1[i]=INF;
}
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
scanf("%d %d %d %d",&u,&v,&w,&w1);
add(u,v,w,w1);
add(v,u,w,w1);
}
d[s]=0;
d1[s]=0;
k=spfa_dfs(s);
printf("%d %d\n",d[t],d1[t]);
}
}
解法五:(Bellman_Ford)
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define INF 0x7ffffff
struct node
{
int to,cost,cost1;
}edge[2000];
int pre[600];
int dis[600],dis1[600];
int n,m,src;
int relax(int u,int v,int cost,int cost1)
{
if(dis[v]>dis[u]+cost||(dis[v]==dis[u]+cost&&dis1[v]>dis1[u]+cost1))
{
dis[v]=dis[u]+cost;
dis1[v]=dis1[u]+cost1;
return 1;
}
else
return 0;
}
int Bellman_Ford()
{
int i,j,flag;
for(i=1;i<=n;i++)
{
dis[i]=INF;
dis1[i]=INF;
}
dis[i]=0;
dis1[i]=0;
for(i=1;i<n;i++)
{
flag=0;
for(j=0;j<m;j++)
{
if(relax(j,edge[j].to,edge[j].cost,edge[j].cost1))
{
pre[j]=edge[j].to;
flag=1;
}
}
if(!flag)
break;
}
for(i=0;i<m;i++)
{
if(relax(i,edge[i].to,edge[i].cost,edge[i].cost1))
return 0;
}
return 1;
}
int main()
{
int i,j,T,t,l1,l2,l3,l4;
scanf("%d",&T);
while(T--)
{
scanf("%d %d %d %d",&n,&m,&src,&t);
for(i=0;i<m;i++)
{
scanf("%d %d %d %d",&l1,&l2,&l3,&l4);
edge[l1].to=l2;
edge[l1].cost=l3;
edge[l1].cost1=l4;
edge[l2].to=l1;
edge[l2].cost=l3;
edge[l2].cost1=l4;
}
Bellman_Ford();
//if(Bellman_Ford())
printf("%d %d\n",dis[t],dis1[t]);
}
}