1. 程式人生 > >圖論之Dijkstra

圖論之Dijkstra

Dijkstra模板:

#include<stdio.h>

#include<string.h>

#define INF 0x11111111

int map[1010][1010];

int way[1010],flag[1010];

int dij(int n)

{

    for(int i=1;i<=n;i++)//開始賦值

    {

        way[i]=map[1][i];

    }

   for(int i=1;i<n;i++)

    {

     int min=INF;

     int k=0;

     for(int j=1;j<=n;j++)//找出一個距離起點最近的路徑

       {

         if(flag[j]==0&&way[j]<min)

           {

                min=way[j];

                k=j;

           }

       }

      flag[k]=1;

      for(int j=1;j<=n;j++)//找出距離剛剛選出來的點最近的距離組成新的路徑

        {

          if(flag[j]==0&&way[k]+map[k][j]<way[j])

            {

              way[j]=way[k]+map[k][j];

            }

        }

     }

}

int main()

{

  intn,m,x,y,z,v,s,t;

 while(scanf("%d %d",&n,&m),n!=0&&m!=0)

     {

       memset(map,INF,sizeof(map));//陣列初始化為最大值

       memset(way,INF,sizeof(way));//此陣列儲存從s到i的長度

       memset(flag,0,sizeof(flag));//標記路徑點是否被加入最短路徑中

       flag[1]=1;//起點已經被標記為加入最短路徑

       for(int i=0;i<m;i++)

       {

          scanf("%d %d %d",&x,&y,&z);

          map[x][y]=z;//儲存正反向的路徑長度和花費

          map[y][x]=z;

       }

       dij(n);

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

     }

   return 0;

   }

find the safest road

                                                                          Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                                          

                                                                          Total Submission(s): 12647    Accepted Submission(s): 4493


Problem Description XX星球有很多城市,每個城市之間有一條或多條飛行通道,但是並不是所有的路都是很安全的,每一條路有一個安全係數s,s是在 0 和 1 間的實數(包括0,1),一條從u 到 v 的通道P 的安全度為Safe(P) = s(e1)*s(e2)…*s(ek) e1,e2,ek是P 上的邊 ,現在8600 想出去旅遊,面對這這麼多的路,他想找一條最安全的路。但是8600 的數學不好,想請你幫忙 ^_^
Input 輸入包括多個測試例項,每個例項包括:
第一行:n。n表示城市的個數n<=1000;
接著是一個n*n的矩陣表示兩個城市之間的安全係數,(0可以理解為那兩個城市之間沒有直接的通道)
接著是Q個8600要旅遊的路線,每行有兩個數字,表示8600所在的城市和要去的城市
Output 如果86無法達到他的目的地,輸出"What a pity!",
其他的輸出這兩個城市之間的最安全道路的安全係數,保留三位小數。
Sample Input 3 1 0.5 0.5 0.5 1 0.4 0.5 0.4 1 3 1 2 2 3 1 3
Sample Output 0.500 0.400 0.500
Author ailyanlu
Source
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<string.h>
using namespace std;
#define INF 0x3f3f3f3f
double map[1010][1010];
double way[1010],flag[1010];
int n;
void dij(int x,int y)
{
    for(int i=1; i<=n; i++)//開始賦值
    {
        way[i]=map[x][i];
    }
    for(int i=1; i<n; i++)
    {
        int k=0;
        double maxx=-INF;
        for(int j=1; j<=n; j++)//找出一個距離起點最近的路徑
        {
            if(flag[j]==0&&way[j]>maxx)
            {
                maxx=way[j];
                k=j;
            }
        }
        flag[k]=1;
        for(int j=1; j<=n; j++)//(以後每考慮一個新的中間點,way[j]的值可能被修改變大)
        {
            if(flag[j]==0&&way[k]*map[k][j]>way[j])
                way[j]=way[k]*map[k][j];
        }
    }
}
int main()
{
    int m,a,b;
    while(~scanf("%d",&n))
    {
        memset(map,0,sizeof(map));
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            scanf("%lf",&map[i][j]);
        scanf("%d",&m);
        while(m--)
        {
            memset(way,INF,sizeof(way));//用來儲存從源點v到頂點i的目前最短路徑長度
            memset(flag,0,sizeof(flag));//標記路徑點是否被加入最短路徑中
            scanf("%d%d",&a,&b);
            dij(a,b);
            if(way[b]!=0)
                printf("%.3lf\n",way[b]);
            else
                printf("What a pity!\n");
        }
    }
}
河南省第九屆程式設計競賽的通道安全因為資料太大,用狄克斯特拉演算法是行不通的。