ACM3790迪杰斯特拉算法运用

最短路径问题

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<n<=1000, 0<m<100000, s != t)
 
Output
输出 一行有两个数, 最短距离及其花费。
 
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
5 7
1 2 5 5 
2 3 4 5
1 3 4 6
3 4 2 2
3 5 4 7
4 5 2 4
1 3 4 4
1 5
 
0 0
 
Sample Output
9 11
8 10

 

  1 #include<iostream>
  2 #include<cstring>
  3 using namespace std;
  4 const int oo=111111;
  5 int **weight,**profit;//权值和花费 
  6 int s,e;
  7 int n,m;
  8 int *low,*vis,*lowp,*pre;
  9 int**Apply_space(int n)
 10 {
 11     int **p;
 12     p=new int*[n+1];
 13     for(int i=0;i<=n;i++)
 14     p[i]=new int[n+1];
 15     return p;
 16 }
 17 void dijkstra()
 18 {
 19     for(int i=1;i<=n;i++)
 20     {
 21         low[i]=weight[s][i];
 22         lowp[i]=profit[s][i];
 23         pre[i]=s;//初始化路径
 24     }
 25     low[s]=lowp[s]=0;
 26     vis[s]=1;
 27     pre[s]=0;
 28     for(int i=1;i<n;i++)
 29     {    
 30         int v;
 31         int Min=oo;
 32         for(int j=1;j<=n;j++)
 33             if(!vis[j]&&low[j]<Min)
 34             {
 35                 Min=low[j];
 36                 v=j;
 37             }
 38         vis[v]=1;
 39         for(int j=1;j<=n;j++)
 40         {
 41         if(!vis[j]&&low[j]>low[v]+weight[v][j])
 42             {
 43                 low[j]=low[v]+weight[v][j];
 44                 lowp[j]=lowp[v]+profit[v][j];
 45                 pre[j]=v;//标记路径
 46             }
 47         else if(!vis[j]&&low[j]==low[v]+weight[v][j])
 48         {
 49             if(lowp[j]>=lowp[v]+profit[v][j])
 50             {
 51                 lowp[j]=lowp[v]+profit[v][j];
 52                 pre[j]=v;//标记路径
 53             }
 54         }
 55         }
 56     }
 57 }
 58 void dfs(int i)//输出路径
 59 {
 60     if(pre[i]==0)
 61     {
 62         cout<<i<<" ";
 63         return;
 64     }
 65     int j=pre[i];
 66     dfs(j);
 67     cout<<i<<" ";
 68 }
 69 int main()
 70 {
 71     while(scanf("%d %d",&n,&m)==2&&(n||m))
 72     {
 73         profit=Apply_space(n);
 74         weight=Apply_space(n);
 75         low=new int[n+1];
 76         vis=new int[n+1]; 
 77         lowp=new int[n+1];
 78         pre=new int[n+1];
 79         for(int i=0;i<=n;i++)
 80         {
 81             vis[i]=0;
 82         }
 83     
 84         for(int i=0;i<=n;i++)
 85         for(int j=0;j<=n;j++)
 86         {
 87             profit[i][j]=(i==j)?0:oo;
 88             weight[i][j]=(i==j)?0:oo;
 89         }
 90         int a,b,c,d;
 91         for(int i=1;i<=m;i++)
 92         {
 93             scanf("%d %d %d %d",&a,&b,&c,&d);
 94             if(weight[a][b]>c)
 95             {
 96                 weight[a][b]=weight[b][a]=c;
 97                 profit[a][b]=profit[b][a]=d;
 98             }
 99             else if(weight[a][b]==c)
100             {
101                 if(profit[a][b]>d)
102                 {
103                     profit[a][b]=profit[b][a]=d;
104                 }
105             }
106         }
107         scanf("%d %d",&s,&e);
108         dijkstra();
109         printf("%d %d\n",low[e],lowp[e]);
110         //dfs(e);//记录路径使用
111         delete []profit;delete []weight;delete []low;delete []vis;
112         delete []pre;
113     }
114     return 0;
115 }

 

posted @ 2014-07-28 23:55  SYTM  阅读(326)  评论(0编辑  收藏  举报