UVA 10099 Kruskal算法 Floyd算法

               题意:给你一张图,找到能够从起点到终点的路径中最小边权的最大值。

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值