题目
题解思路
求两点之间 路径中 最大的最小边
和上一题有点类似,还是根据迪杰斯特拉的思想,如何保证此时路径最大呢? 我们只要在松弛的时候,每次取和原点的路径最大的点来进行松弛,就可以保证此时松弛出来的结果是最大的了。然后每次取最小的边即可。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int inf = 1e6 + 5;
int mp [1005][1005] ;
struct d
{
int w,ma;
}dis[1005];
bool vis [1005];
int main ()
{
std::ios::sync_with_stdio(false);
int t;
while(cin>>t)
{
int sum = 1 ;
while ( t-- )
{
int n,m;
cin>>n>>m;
memset(vis, 0 ,sizeof(vis) ) ;
memset (mp, 0 , sizeof(mp) );
for (int i = 1 ;i <= m ;i++ )
{
int a,b,c;
cin>>a>>b>>c;
mp [ a ][ b ] = c;
mp [ b ][ a ] = c;
}
for (int i = 1 ;i <= n ; i++ )
{
dis[ i ].w = mp [ 1 ][ i ];
dis[ i ].ma = mp [ 1 ][ i ] ;
}
vis [ 1 ] = 1 ;
for (int i = 1 ;i <= n ; i++ )
{
int t =1 ,t1 = 0 ;
for (int k = 1; k <= n ; k++ )
{
if (vis[ k ] == 0 && dis[k].w > t1 )
{
t1 = dis [ k ] .w;
t = k;
}
}
vis [ t ] = 1;
for (int k = 1 ;k <= n ; k++ )
{
if ( mp[ t ][ k ] != 0 )
{
// if ( dis [ k ].w < mp[ t ][ k ] + dis [t].w || dis [k] .w == 1162167621 )
// {
// printf("此时使用%d来松弛\n" , t);
// printf("dis[%d].w= %d " , k,dis[k].w);
// dis [ k ] .w = mp[ t ][ k ] + dis [t].w ;
// printf("dis[%d].w= %d " , k,dis[k].w);
// printf("dis[%d]. ma= %d " , k,dis[k].ma);
// dis [ k ] . ma = min( mp [ t ][ k ], dis [k] .ma );
// printf("dis[%d]. ma= %d \n" , k,dis[k].ma);
// }
if (dis [ k ] . w < min(mp[ t ][ k ] , dis [t].w ) )
{
printf("use %d %d \n",t,min(mp[ t ][ k ] , dis [t].w ));
printf("dis[%d].w= %d " , k,dis[k].w);
dis [ k ] .w = max ( dis[ k ] .w , min(mp[ t ][ k ] , dis [t].w ) );
printf("dis[%d].w= %d \n" , k,dis[k].w);
}
}
}
}
cout<<"Scenario #"<<sum<<":\n";
sum++;
cout<<dis[ n ].w<<"\n\n";
}
}
return 0;
}