圖論之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
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");
}
}
}
河南省第九屆程式設計競賽的通道安全因為資料太大,用狄克斯特拉演算法是行不通的。