这道题要求我们求出图中的给定的两个节点(一个起点一个终点,但这是无向图)之间所有“路径中最大权值”的最小值,这无疑是动态规划。
我开始时想到根据起点和终点用动态规划直接求结果,但最终由于题中S过大,会超时。
超时的代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <algorithm>
using namespace std;
const int MAX = 1000000;
int w[100][100];
int vis[100];
int C,S,Q;
int f(int s, int t)
{
vis[t]=1;
int minb=MAX,tmp;
for(int i=0; i<C; i++) if(!vis[i] && w[t][i]!=-1)
{
if(i==s) { minb=w[t][i]; continue;}
tmp = f(s,i);
tmp = (tmp > w[t][i] ? tmp : w[t][i]);
minb = (minb < tmp ? minb : tmp);
}
vis[t]=0;
return minb;
}
int main()
{
int c1,c2;
int Case=0;
while(cin >> C >> S >> Q && C!=0)
{
memset(w,-1,sizeof(w));
for(int i=0; i<S; i++) {
cin >> c1 >> c2; cin >> w[c1-1][c2-1]; w[c2-1][c1-1]=w[c1-1][c2-1];
}
if(Case) cout << endl;
cout << "Case #" << ++Case << endl;
while(Q--)
{
memset(vis,0,sizeof(vis));
cin >> c1 >> c2;
int ans = f(c1-1,c2-1);
if(ans==MAX) cout << "no path\n";
else cout << ans << endl;
}
}
return 0;
}
被判超时后想到,由于S过大,即要求的起始节点对过多,最好一次性全部求出来。在uva的board中看到别人有使用Floyd_WarShall算法的,受到启发,就自己思考了一下。
Floyd_WarShall算法本身肯定无法完成这题的解答,但只要改写其更新节点值的式子就可以解决这道题。我将更改后的算法命名为Floyd_WarShallEx,代码如下:
void Floyd_WarShallEx()
{
for(int k=0; k<C; k++)
{
for(int i=0; i<C; i++)
{