uva10099 (floyd & 最大生成树)

题目大意:
有一个导游,要将游客从城市i送到城市j,有的城市之间是有公交车可以直达的,但是公交车是有限制人数的。问导游需要多少趟才能把所有的游客从城市i送到城市j。

思路:
其实这道题说白了就是算从城市i到j的路径当中,要找出一条路径的最小值是所有路径最小值当中最大的。
floyd算法:
d[i][j] = max(d[i][j],min(d[i][k],d[k][j]));

kruskal算法:
将城市之间的公交车的限载人数作为权值从大到小排序形成一个优先级队列。然后不断的添加边,直到可以将城市i,j连接起来,这时候这个权值就是要求的,即最小值中的最大值。

代码:
floyd算法:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
#include <algorithm>
const int N = 105;
const int INF = 0x3f3f3f3f;

int n,m,start,e,limit,d[N][N];
void floyd()  {
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            for(int k = 1; k <= n; k++) {
                int temp = min(d[j][i],d[i][k]);
                if(d[j][k] == INF) d[j][k] = temp;
                else
                    d[j][k] = max(d[j][k],temp);
            }
        }
    }
}
int main() {

    int T = 0;
    while(scanf("%d %d",&n,&m) && n && m) {
        for(int i = 1; i <= n; i++){
            d[i][i] = 0;
            for(int j = i + 1; j <= n; j++)
                d[i][j] = d[j][i] = INF;
        }
        int a,b,c;
        for(int i = 0; i < m; i++) {
            scanf("%d %d %d",&a,&b,&c);
            d[a][b] = d[b][a] = c;
        }
        floyd();
        scanf("%d %d %d",&start,&e,&limit);
        int ans = d[start][e];
    //  printf("%d",ans);
        if(limit %(ans - 1) == 0)    {
            ans = limit/(ans - 1);
        }
        else
            ans = limit/(ans - 1) + 1;
        printf("Scenario #%d\n",++T);
        printf("Minimum Number of Trips = %d\n\n",ans);
    }
    return 0;
}

kruskal算法:

#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <cmath>
#include <algorithm>

const int N = 10005;

int n,m,start,e,limit,f[N];

struct node {
    int u,v,w;
    friend bool operator < (const node &a,const node &b)  {
        return a.w > b.w;
    }
}arr[N];

int find(int x) {
    int i,j,k = x;
    while(k != f[k])
        k = f[k];
    i = x;
    while(i != k) {
        j = f[i];
        f[i] = k;
        i = j;
    }
    return k;
}

bool Union(int i,int j) {
    int x = find(i);
    int y = find(j);
    if(x == y)
        return false;
    else
        f[x] = y;
    return true;
}
int main() {

    int x,y,w;
    int T = 0;
    while(scanf("%d %d",&n,&m) && n && m) {
        for(int i = 0; i <= n; i++)
            f[i] = i;
        for(int i = 0; i < m; i++) {
            scanf("%d %d %d",&arr[i].u,&arr[i].v,&arr[i].w);
        }
        sort(arr,arr + m);
        scanf("%d %d %d",&start,&e,&limit);
        int i;
        for(i = 0; i < m; i++) {
            if(Union(arr[i].u,arr[i].v)) {
                int a = find(start);
                int b = find(e);
                if(a == b)
                    break;
            }
        }
        printf("Scenario #%d\n",++T);
        int ans = arr[i].w;
        if(limit %(ans - 1) == 0)
            ans = limit /(ans - 1);
        else
            ans = limit /(ans - 1) + 1;
        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、付费专栏及课程。

余额充值