题意:给你一张图,找到能够从起点到终点的路径中最小边权的最大值。
Kruskal算法:
按照权值由大到小的顺序排序所有的边,模拟Kruskal算法,一条一条往里加边,直到起点和终点在一个集合中(表明起点和终点联通了),此时所加的边的权值就是这条路径中的最小值了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define MAXN 9910
using namespace std;
typedef struct node
{
int u,v,w;
node(int x=0,int y=0, int z=0)
{
u=x,v=y,w=z;
}
bool operator <(const node &th) const
{
return th.w<w;
}
} node;
node edge[MAXN];
int p[101];
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
int main()
{
// freopen("in.txt","r",stdin);
int n,r,cas=0;
while(scanf("%d%d",&n,&r)&&n+r)
{
for(int i=0; i<r; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
node g(a,b,c);
edge[i]=g;
}
sort(edge,edge+r);// from large to small
for(int i=1; i<=n; i++)
p[i]=i;
int s,d,t,ans;
scanf("%d%d%d",&s,&d,&t);
for(int i=0; i<r; i++)
{
int tx=find(edge[i].u);
int ty=find(edge[i].v);
if(tx!=ty)
p[tx]=ty;
int x=find(s);
int y=find(d);
if(x==y)
{
ans=edge[i].w-1;
break;
}
}
printf("Scenario #%d\n",++cas);
printf("Minimum Number of Trips = %d\n\n",t%ans?t/ans+1:t/ans);
}
return 0;
}
Floyd算法:
稍稍改进一下floyd算法中第三个for循环的内容,d数组保存的不是两点之间的最短路,而是两点之间的最小权值的最大值。这样d数组的初始化:d[i][i]=INF,其他d值为0。
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 105
#define INF 10000
using namespace std;
int d[MAXN][MAXN];
int main()
{
// freopen("in.txt","r",stdin);
int n,r,cas=0;
while(scanf("%d%d",&n,&r)&&(n+r))
{
cas++;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
if(i==j) d[i][j]=INF;
else d[i][j]=0;
}
for(int i=0; i<r; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
d[a][b]=d[b][a]=c;
}
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
d[i][j]=max(d[i][j],min(d[i][k],d[k][j]));
int s,dd,t;
scanf("%d%d%d",&s,&dd,&t);
int ans=d[s][dd]-1;
if(t%ans) ans=t/ans+1;
else ans=t/ans;
printf("Scenario #%d\n",cas);
printf("Minimum Number of Trips = %d\n\n",ans);
}
return 0;
}