题意:
给定n,m n代表街道数,m代表连接两个街道的桥的数量,又给出m个a,b,c(a为起点街道,b为中点街道,c为这两个街道的桥的承受重量),问走过所有街道,找到承重最大的路径的最小边。(找最大路径最小边)
解法:
在dijkstra基础上的变形,
每次在已经得到的最大容量路里找最大的,然后用他去松弛其他点 (松弛过程中变形为:找该最大容量路的最小边)
(与poj2253的变形刚好相反)
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int dis[1010];
int maps[1010][1010];
int vis[1010];
int n,m;
int min(int a,int b)
{
return a<b?a:b;
}
int max(int a,int b)
{
return a>b?a:b;
}
void dijkstra(int n)
{
int maxx,k;
maxx=0;
for(int i=1;i<=n;i++)
{
vis[i]=0;
dis[i]=maps[1][i];
}
vis[1]=1;
for(int i=1;i<n;i++)
{
k=0;
maxx=0;
for(int j=1;j<=n;j++) //寻找最大路径 ,同样有变化
{
if(vis[j]==0&&maxx<=dis[j])
{
maxx=dis[j];
k=j;
}
}
vis[k]=1;
if(vis[n]==1) return;
for(int j=1;j<=n;j++)
{
if(vis[j]==0)
{
dis[j]=max(dis[j],min(dis[k],maps[k][j])); //松弛变形,min()代表找该路径的最小边,max()代表找两个不同路径的最大路径,再将这个路径的最小边保存起来
}
}
}
}
int main()
{
int cases;
scanf("%d",&cases);
for(int i=1;i<=cases;i++)
{
scanf("%d%d",&n,&m);
memset(maps,0,sizeof(maps));
for(int j=0;j<m;j++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(maps[a][b]<c)
{
maps[a][b]=c;
maps[b][a]=c;
}
}
dijkstra(n);
printf("Scenario #%d:\n",i);
printf("%d\n\n",dis[n]);
}
return 0;
}