1.1 原题目链接
1.2 解题思路
此题相当于简单有向图的最短路径问题,只是把总消耗改为路径上最高权值。
最短路算法在《数据结构》图的章节有介绍两种经典的算法:Dijkstra,Floyd-Warshall。用Floyd算法代码会更简单,且代码紧凑,并不包含复杂的数据结构,因此算法复杂度隐含的常系数很小,即使对于中等规模的输入来说,仍然相当有效(该句引自文献[1]第99页)。网上有相应代码,引用自:(CSDN ID)tao_tao_bu_jue
#include <iostream> using namespace std; int n,m,t; const int inf=1000000000; int mat[301][301]; int MAX(int a,int b){return a>b?a:b;} void floyd() { int i,j,k; for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i==j||i==k||j==k) continue; if(MAX(mat[i][k],mat[k][j])<mat[i][j]) mat[i][j]=MAX(mat[i][k],mat[k][j]); } } int main() { int i,j,s,e,len; while(scanf("%d%d%d",&n,&m,&t)!=EOF){ for(i=1;i<=n;i++) for(j=1;j<=n;j++) mat[i][j]=inf; while(m--) { scanf("%d%d%d",&s,&e,&len); mat[s][e]=len; } floyd(); while(t--) { scanf("%d%d",&s,&e); printf("%d\n",mat[s][e]==inf?-1:mat[s][e]); } } }
此处我用Dijkstra方法求解,并使用(前向)星形表示法的数据结构,代码肯定比Floyd的复杂,我主要是做效率上的测试。想了解星形表示法的读者请下载参考文献[2],图与网络那章有做详细的介绍。
AC时间:2013-09-08 20:46:05
#include <stdio.h> #include <string.h> #include <algorithm> #include <vector> using namespace std; #define MAXN 310 #define VNUM 25010 #define Inf 1000000000 struct MsgType { int v1; int v2; int w; bool operator< (const MsgType&rhs) const { if( v1 - rhs.v1 ) return v1 < rhs.v1; else return v2 < rhs.v2; } }; int N,M,T; int v1[VNUM], v2[VNUM], w[VNUM], index[MAXN]; vector<MsgType> MsgTable; void GetData() { int i, val; MsgType t; vector<MsgType>::iterator it; for( i = 0; i < M; i++ ) { scanf("%d%d%d",&t.v1,&t.v2,&t.w); MsgTable.push_back(t); } sort( MsgTable.begin(), MsgTable.end() ); memset( index, -1, sizeof(int)*(N+1) ); it = MsgTable.begin(); index[1] = 1; v1[1] = (*it).v1; v2[1] = (*it).v2; w[1] = (*it).w; it++; for( i = 2; i <= M; i++, it++ ) { if( (*it).v1 != v1[i-1] ) index[ (*it).v1 ] = i; v1[i] = (*it).v1; v2[i] = (*it).v2; w[i] = (*it).w; } MsgTable.clear(); index[ N+1 ] = M + 1; for(val = M + 1, i = N; i > 0; i-- ) { if( index[i] == -1 ) index[i] = val; else val = index[i]; } } void Dijkstra( int start, int end, int dist[MAXN] ) { int i, min, tmp, p, small,logo ; bool mark[MAXN]={0}; mark[start] = 1; for( i = 1; i <= N; i++ ) dist[i] = Inf; for( i = index[start], tmp = index[start+1]; i < tmp; i++ ) dist[ v2[i] ] = w[i]; while(1) { for(logo=1, min = Inf, i = 1; i <= N; i++ ) if( !mark[i] ) if( dist[i] < min ) { logo = 0; min = dist[i]; p = i; } if( logo ) break; mark[p] = 1; tmp = index[p+1]; for( i = index[p]; i < tmp; i++ ) if( !mark[ v2[i] ] ) { small = min > w[i] ? min:w[i]; if( small < dist[ v2[i] ] ) dist[ v2[i] ] = small; } } } int main() { int start, end, mark[MAXN], dist[MAXN][MAXN]; while( scanf("%d%d%d",&N,&M,&T)!=EOF ) { GetData(); memset(mark,0,sizeof(int)*MAXN); while( T-- ) { scanf( "%d%d", &start, &end ); if( !mark[start] ) { mark[start] = 1; Dijkstra(start,end,dist[start]); } if( dist[start][end] == Inf ) printf("-1\n"); else printf("%d\n",dist[start][end]); } } return 0; }
[1] 王道论坛,2013年计算机专业基础综合考试指导全书,长沙:中南大学出版社,2012
[2] 作者不祥(网络资源),(书名)Matlab数学建模算法全收录,百度网盘下载