图结构练习——最短路径
Time Limit: 1000MS
Memory Limit: 65536KB
Problem Description
给定一个带权无向图,求节点1到节点n的最短路径。
Input
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表节点个数和边的个数。(n<=100)
剩下m行每行3个正整数a b c,代表节点a和节点b之间有一条边,权值为c。
Output
每组输出占一行,仅输出从1到n的最短路径权值。(保证最短路径存在)
Example Input
3 2 1 2 1 1 3 1 1 0
Example Output
1 0
#include<stdio.h> #define MAXINT 65535 #define N 10005 int Pic[N][N]; int PointValue[N]; int Path[N]; int Check[N]; int front=0; int rear=0; void Init(int l){ int row; int col; int v; for(int i=0;i<l;i++){ scanf("%d %d %d",&row,&col,&v); if(Pic[row-1][col-1]>v){ Pic[row-1][col-1]=v; Pic[col-1][row-1]=v; } } } void RollBack(int n){ for(int i=0;i<n;i++){ PointValue[i]=0; Path[i]=0; Check[i]=0; for(int j=0;j<n;j++){ Pic[i][j]=MAXINT; } } front=0; rear=0; } int Mix(int a[],int n){ int Mix=MAXINT; int k=0; for(int i=0;i<n;i++){ if(!Check[i]&&Mix>a[i]){ Mix=a[i]; k=i; } } return k; } void ShortPath(int start,int end,int n){ PointValue[0]=0; Path[rear++]=start; Check[start]=1; for(int i=1;i<n;i++){ if(Pic[start][i]) PointValue[i]=Pic[start][i]; else PointValue[i]=MAXINT; } int j=1; int Num=n-1; while(Num--){ for(int k=0;k<n;k++){ if(Pic[j][k]&&PointValue[j]+Pic[j][k]<PointValue[k]&&!Check[k]){ PointValue[k]=PointValue[j]+Pic[j][k]; } } int v=Mix(PointValue,n); Check[v]=1; Path[rear++]=v; j=v; } } int main(){ int k,m; while(scanf("%d %d",&k,&m)!=EOF){ RollBack(k); Init(m); ShortPath(0,k,k); printf("%d\n",PointValue[k-1]); //printf("\n"); } return 0; }
提交了好几次都没过,之前没有考虑这是无向图,所拥有的边可能不只一条,即最先输入的边不一定是最小的,这需要再输入的时候加以确认。
最短路径Dijkstra算法
Check数组 检测该点是否被访问;
PointValue数组 动态保存由原点到该点的最短距离;
Pic邻接矩阵保存各个点之间的关系(权值);
通过一个一维数组保存又原点到该点的最短距离,并将此点设置为已访问,在从该点开始访问与之相连的各个节点,dk=Mix(dk,dj+(path:由j-k的路径长)/*Pic[j][k]*/)
循环遍历,直到所有的点全部访问完毕!