天天看点

hdu3790 最短路径问题(dijkstra/优先队列实现)

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 16613    Accepted Submission(s): 4973

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
0 0      

Sample Output

9 11      

Source

​​浙大计算机研究生复试上机考试-2010年​​

还记得第一次看这道题是acm队员选拔的时候,那时候看的云里雾里,更不知道什么是dijkstra,prim,kruskal等等...

到现在三个月过去了,能靠自己ac这道题,也是进步。

废话不说,这道题就是dijkstra最短路径问题。这道题也要注意重边的问题。判断一下就行。

具体看代码:

#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
int n,m,cost[1005][1005],len[1005][1005],vis[1005];//cost存贮花费,len存贮长度,vis标记
struct node
{
  int pay,l,pos;
  friend bool operator< (const node a,const node b)//根据题意要求,如果路径相等按照花费排序
  {
    if(a.l>b.l) return true;
    if(b.l==a.l&&a.pay>b.pay) return true;
    return false;
  }
};
priority_queue<node>s;
void dijkstra(int star,int end)
{
  node temp,x;
  temp.pos=star,temp.l=0,temp.pay=0;
  s.push(temp);
  while(!s.empty())
  {
    temp=s.top();
    s.pop();
    star=temp.pos;
    if(star==end)
    break;
    x=temp;
    for(int i=1;i<=n;i++)//从1开始
    {
      if(!vis[i]&&len[star][i]<1000000)
      {
        temp.l+=len[star][i];
        temp.pay+=cost[star][i];
        temp.pos=i;
        s.push(temp);
        vis[star]=1;
      }
      temp=x;
    }
  }
  printf("%d %d\n",temp.l,temp.pay);
}
int main()
{
  int star,end;
  while(scanf("%d %d",&n,&m)!=EOF,(m||n))
  {
    memset(vis,0,sizeof(vis));
    memset(cost,100,sizeof(cost));
    memset(len,100,sizeof(len));
    for(int i=0;i<m;i++)
    {
      int a,b,d,p;
      scanf("%d %d %d %d",&a,&b,&d,&p);
      if(d<len[a][b]||(d==len[a][b]&&p<cost[a][b]))//避免重边,判断一下
      len[a][b]=len[b][a]=d,cost[a][b]=cost[b][a]=p;;
      
    }
    scanf("%d %d",&star,&end);
    dijkstra(star,end);
    while(!s.empty())
    s.pop();
  }
  return 0;
}