UESTC 1053 Shortest road

//题目类型;最短路-求最短路的条数
//解题思路:类似于贪心的思路,基本方法为采用递推,用 p[] 记录路径条数,
//(1)dist[u]+ w(u,v)== dist[v] ,则 p[v]+= p[u]
//(2)dist[u]+ w(u,v)< dist[v] 则 p[v]= p[u]。
//由于本题边数较多,所以采用邻接表的结构存储
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
//#include <conio.h>
using namespace std;
                                
const int MAXN = 1001;    //点数         
const int marray = 1000001;
const int INF=0x7fffffff; 
struct edge_T {
     int v;
     int w;
     edge_T *next;
}*adj[MAXN], edges[2*marray];     
struct node_T {             
     int v;
     int len;
     bool operator < (const node_T &nod) const {
          return len > nod.len;
     }
};
int edgenum;              //记录边的总数
int vn,en;             //记录定点数和边数
int path[MAXN];
int dist[MAXN];
int src,des;
void addEdge(int u, int v, int w) {   
     edge_T *ptr = &edges[edgenum ++];
     ptr -> v = v;
     ptr -> w = w;
     ptr -> next = adj[u];    //往前插入边
     adj[u] = ptr;
}
void dijkstra(int s) {             //n代表结点总数
     priority_queue <node_T> Q;            //使用优先级队列实现
     node_T cur;
     cur.v = s;
     cur.len = 0;
     Q.push(cur);
     for(int i = 1; i <= vn; i ++)
     {
          dist[i] = INF;
          path[i] = 0;
     }      
     dist[s] = 0;
     path[s] = 1;
     while(! Q.empty()) {
          int v = Q.top().v;               //优先级队列使用top()
          int len = Q.top().len;
          Q.pop();
          if(dist[v]!=len) continue;
          for(edge_T *ptr = adj[v]; ptr; ptr = ptr -> next) {
               int u = ptr -> v;
               int w = ptr -> w;
               if(dist[v] + w < dist[u]) {
                    dist[u] = dist[v] + w;
                    cur.v = u;
                    cur.len = dist[u];
                    Q.push(cur);
                   
                    path[u] = path[v];  //此处是关键
               }
               else if(dist[v]+w==dist[u])
               {
                    path[u] += path[v];   //此处是关键
               }
          }
     }    
}
int main() {
      //freopen("1.txt","r",stdin);
      int t;
      int i;
      int src;
      scanf("%d",&t);
      while(t--)
      {
          scanf("%d %d", &vn, &en);
          for(i = 1; i <= vn; i ++)
          {
               adj[i] = NULL;                //初始化邻接表的指针
          }
          edgenum = 0;                       //初始化边数
          int u, v;
          int w;
          for(i = 1; i <= en; i ++)
          {       
               scanf("%d%d%d", &u, &v, &w); //最好采用此种读取方式,下边一种在某些题目中会出错
               addEdge(u, v, w);
               addEdge(v, u, w);
          }
          scanf("%d%d",&src,&des);
          dijkstra(src);
          if(dist[des]==INF) printf("0\n0\n\n");
          else  printf("%d\n%d\n\n",dist[des],path[des]);
      }    
      //getch();
      return 0;
}

 

你可能感兴趣的:(test)