最短路径问题(Dijkstra)

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

 

 

Output

输出 一行有两个数, 最短距离及其花费。

 

 

Sample Input

 

3 2 1 2 5 6 2 3 4 5 1 3 0 0

 

 

Sample Output

 

9

11

      这个问题一看就用Dijkstra,不过又加了个费用,多设立个数组即可。但是我被卡了很多次,一直不知道卡在那里,重复检查多次,自己也设置数据,依旧没发现问题,但是就是Wa,后来拿来大神出的一组数据一测,我去 ,原来是在输入数据的时候贪心的选择了费用,这个题费用受路径限制啊!要根据路径选择费用。。。。。

  注意细节,注意细节,注意细节。。。重要的事情的说三遍,有时你会发现你和AC的距离就差一层窗户纸的距离,必须全神贯注的顺一遍题意,捋一遍程序才行。

AC  Code

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PI  3.14159265358979
#define LL long long
const int INF=0x3f3f3f3f;
using namespace std;
int w[1010][1010];//路径数组
int d[1005];//储存最短路径
int tt[1005];//储存最小费用
int TIME[1005][1005];//费用数组
bool vis[1005];
int main()
{
    //freopen("1.txt","r",stdin);
   int T,n,m,f,t,dis,tim;
   while(scanf("%d%d",&n,&m)==2&&n+m)
   {
       memset(w,0x3f,sizeof(w));
       memset(vis,0,sizeof(vis));
       memset(TIME,0x3f,sizeof(TIME));
       memset(d,0x3f,sizeof(d));
       memset(tt,0x3f,sizeof(tt));
       for(int i=1;i<=m;++i)
       {
           scanf("%d%d%d%d",&f,&t,&dis,&tim);
           if(w[f][t]>dis) {//路径贪心选择,而费用要根据路径选择,这种情况就不能选择
               w[f][t]=w[t][f]=dis;
            TIME[f][t]=TIME[t][f]=tim;
           }
           else if(w[f][t]==dis){//这种情况费用贪心选取
            if(TIME[f][t]>tim) TIME[f][t]=TIME[t][f]=tim;
           }
       }
       int a,b;
       scanf("%d%d",&a,&b);
       d[a]=0;tt[a]=0;
       for(int i=1;i<=n;++i)
       {
           int x,m=INF;
           for(int y=1;y<=n;++y) if(!vis[y]&&d[y]<=m) m=d[x=y];
           vis[x]=1;
           for(int y=1;y<=n;++y)  if(d[y]>d[x]+w[x][y]) {d[y]=d[x]+w[x][y];tt[y]=tt[x]+TIME[x][y];}
                                  else if(d[y]==d[x]+w[x][y]) {
                                    if(tt[y]>tt[x]+TIME[x][y]) tt[y]=tt[x]+TIME[x][y];
                                  }


   }

     printf("%d %d\n",d[b],tt[b]);


}}

感谢大牛的数据

/*
//测试数据 
2 2
1 2 5 10
2 1 4 12
1 2
4 12

4 4
1 2 5 6
2 3 4 5
1 4 5 10
4 3 4 2
1 3
9 11

6 7
1 2 5 6
1 3 5 1
2 6 2 1
3 4 1 1
4 2 1 1
4 5 1 1
5 2 3 1
5 6
4 3
*/
 

你可能感兴趣的:(图论——最短路)