题目1008:最短路径问题

来源:互联网 发布:观察者模式 java 编辑:程序博客网 时间:2024/06/05 14:23
题目1008:最短路径问题

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:11139

解决:3795

题目描述:
给你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<n<=1000, 0<m<100000, s != t)
输出:
输出 一行有两个数, 最短距离及其花费。
样例输入:
3 21 2 5 62 3 4 51 30 0
样例输出:
9 11
来源:
2010年浙江大学计算机及软件工程研究生机试真题
答疑:

解题遇到问题?分享解题心得?讨论本题请访问:http://t.jobdu.com/thread-7732-1-1.html

分析:自己用的是Dijkstra算法写的,感觉特别好;大致思想也就是找权值最小的边,如果有边相等,则找花费最小的边。

#include <iostream>#include <fstream>using namespace std;struct cost{int d;//距离 int p;// 花费 }dist[1001];struct graph{int n,e; //节点数和边数 }g;int mapd[1001][10001];//存的是边的距离 int mapp[1001][10001]; //存的是边的花费 const int INF = 2100000000; //这里视为权值无穷大 int path[1001];//记录选取的中间节点 void Dijkstra(graph g,int s0);int main(){ifstream in;in.open("1.txt");int n,m;int s0,s1;while(in>>n>>m,n||m)//当且仅当n和m全为false时表达式的值为false,否则为true,{//也就是如果n和m中只要有一个不为0表达式的值就为1,while就一直循环g.n=n;g.e=m;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){mapd[i][j]=INF; mapp[i][j]=INF;} for(int i=1;i<=m;i++){int j,k;in>>j>>k;in>>mapd[j][k]>>mapp[j][k];//无向图,二个方向都要设置权值 mapd[k][j]=mapd[j][k];mapp[k][j]=mapp[j][k];}in>>s0>>s1; Dijkstra(g,s0);cout<<dist[s1].d<<" "<<dist[s1].p<<endl;}return 0; } void Dijkstra(graph g,int s0) { int set[1001];//节点访问的标志  int min1,min2,i,j,u; for(i=1;i<=g.n;i++) { dist[i].d=mapd[s0][i]; dist[i].p=mapp[s0][i]; set[i]=0; if(mapd[s0][i]<INF) path[i]=s0; else path[i]=-1;} set[s0]=1;path[s0]=-1;for(int i=1;i<=g.n;i++){min1=INF;//距离的最小值 min2=INF;//花费的最小值 for(j=1;j<=g.n;j++){if(set[j]==0 && dist[j].d<min1)//选择距离小的边 {u=j;min1=dist[j].d;min2=dist[j].p;}else if(set[j]==0 && dist[j].d==min1 && dist[j].p<min2)//若边的距离相等,选择花费小的边 {u=j;min1=dist[j].d;min2=dist[j].p;}}set[u]=1;//将其加入到最短路径的点集里 for(j=1;j<=g.n;j++){if(set[j]==0 && dist[u].d+mapd[u][j]<dist[j].d){dist[j].d=dist[u].d+mapd[u][j];dist[j].p=dist[u].p+mapp[u][j];path[j]=u;}else if(set[j]==0 && dist[u].d+mapd[u][j]==dist[j].d && dist[u].p+mapp[u][j]<dist[j].p){dist[j].d=dist[u].d+mapd[u][j];dist[j].p=dist[u].p+mapp[u][j];path[j]=u;}}} }

自己又用Floyd写了,但由于这个算法的复杂度为o(n^3),所以提交时间通不过

#include <iostream>#include <fstream>using namespace std;int a[1001][1001];int b[1001][1001];const int INF=210000;void Floyd(int n);int main(){ifstream in;in.open("1.txt");int n,m;int s,t; while(in>>n>>m,m||n){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)b[i][j]=a[i][j]=INF;for(int i=1;i<=m;i++){int j,k;in>>j>>k;in>>a[j][k]>>b[j][k];a[k][j]=a[j][k];b[k][j]=b[j][k];}in>>s>>t;Floyd(n);cout<<a[s][t]<<" "<<b[s][t]<<endl;} return 0;}void Floyd(int n){int i,j,k;for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(a[i][j]>a[i][k]+a[k][j]){a[i][j]=a[i][k]+a[k][j];b[i][j]=b[i][k]+b[k][j];}else if(a[i][j]==a[i][k]+a[k][j] && b[i][j]>b[i][k]+b[k][j]){b[i][j]=b[i][k]+b[k][j];}}}

找了一下别人写的

#include <cstdio>  #include <cmath>  #include <algorithm>  #include <iostream>    using namespace std;    int n, m;  int map[1010][1010];  bool vi[1010];  int cost[1010][1010];  int dis[1010];  int price[1010];  int s, t;    const int INF = 2100000000;    void init()  {      for (int i = 1; i <= n; ++ i)      {          vi[i] = false;          dis[i] = INF;          price[i] = INF;          for (int j = 1; j <= n; ++ j)          {              map[i][j] = INF;          }      }      for (int i = 0; i < m; ++ i)      {          int from, to, d, p;          scanf("%d%d%d%d", &from, &to, &d, &p);          map[to][from] = map[from][to] = d;          cost[to][from] = cost[from][to] = p;      }      scanf("%d%d", &s, &t);    }    void dijkstra()  {      dis[s] = 0;      price[s] = 0;             for (int k = 0; k < n; ++ k)      {          int index = -1;          int minn = INF;          for (int i = 1; i <= n; ++ i)          {              if (vi[i]==false && dis[i]<minn)              {                  index = i;                  minn = dis[i];              }          }          vi[index] = true;                 for (int j = 1; j <= n; ++ j)          {              if (dis[j] > dis[index] + map[index][j])              {                  dis[j] = dis[index] + map[index][j];                  price[j] = price[index] + cost[index][j];               } else if (dis[j] == dis[index] + map[index][j])              {                  price[j] = min(price[j], price[index]+cost[index][j]);              }          }      }  }    int main()  {      while (cin >> n >> m, n || m)      {          init();          dijkstra();          cout << dis[t] << " " << price[t] << endl;      }      return 0;  }  



0 0
原创粉丝点击