1. 程式人生 > >資料結構實驗之圖論七:驢友計劃 (Dijkstra演算法詳解)

資料結構實驗之圖論七:驢友計劃 (Dijkstra演算法詳解)

#include<bits/stdc++.h>
#define MAX INT_MAX //int型裡面最大的數

using namespace std ;

int n , m ; //頂點數,邊數;

int Map[550][550] ; //存放點與點之間的權值;

int vis[550] ; //點的訪問情況 ;

int money[550][550] ; //存放點與點之間的過路費 ;


void Dijkstra(int n , int v0, int vn)
{
    int dist[550] ; //存放v0到vn的最短路徑 ;
    int mon[550] ;
    for(int i=0;i<n;i++)
    {
        dist[i] = Map[v0][i] ; //每個點的最短路徑都設為與起點相連邊上的權值,(不與起點相連的點dist[]陣列的值為MAX)
        mon[i] = money[v0][i] ;//每個點的過路費都初始化成與起點v0相連邊上的費用。
    }
    vis[v0] = 1 ;  //---->|
    dist[v0] = 0 ;    //  |---->對起點的初始化。
    mon[v0] = 0 ; //----->|
    for(int i=1;i<n;i++) //除了起點一共n-1個點 ;
    {
        int MIN = MAX  ; //先取一個無窮大的數,可以方便以後的替換其他的值; 
        int k = v0 ; //記錄最短路徑相關點的下標; 
        for(int j=0 ; j<n ; j++) //找出與起始點相連最短的路徑;
        {
            if(vis[j]==0&&dist[j]<MIN) //如果這個點沒有被訪問過,而且這個點的最短路徑比min小;(這個迴圈的作用是找出與起點v0相連的點所形成的邊,那個邊的權值最小(最短路徑最短))
            {
                MIN = dist[j]  ;
                k = j ;
            }
        }
        vis[k] = 1 ; //改變相關點訪問狀態;
        int j ;
        for(j=0;j<n;j++)
        {
            if(vis[j]==0&&Map[k][j]<MAX) //如果這個點沒被訪問過。而且這個點j與點k之間存在邊的話(Map[k][j]<MAX意思是k,j之間有邊連線)
            {
                if(Map[k][j]+dist[k]<dist[j]) //這個點與k點的路徑+起點v0到k的最短路徑 < 起點v0到j的最短路徑
                {
                     dist[j] = Map[k][j] + dist[k] ;
                     mon[j] = mon[j] + money[k][j] ;
                }
                else if(dist[k]+Map[k][j]==dist[j]&&mon[k]+money[k][j]<mon[j]) //路徑相同,錢不同 ; 
                {
                    mon[j] = mon[j] + Map[k][j] ;
                }
            }
        }
    }
    printf("%d %d\n",dist[vn],mon[vn]) ;
}




int main()
{
    int  t ;
    scanf("%d",&t) ;
    while(t--)
    {
        int v0 , vn ;
        scanf("%d %d %d %d",&n,&m,&v0,&vn);
        int i , j ;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(i==j)
                    Map[i][j] = 0 ;
                else
                    Map[i][j] = MAX ;
            }
        }
        memset(vis,0,sizeof(vis)) ;
        int u , v , t , s ;
        for(i=0;i<m;i++)
        {
            scanf("%d %d %d %d",&u,&v,&t,&s);
            Map[u][v] = Map[v][u] = t ;
            money[u][v] = money[v][u] = s ;
        }
        Dijkstra(n,v0,vn) ;
    }
    return 0 ;
}