HDU 5624

KK的城市重建挑战

传送门 :

KK's Reconstruction

 


Our lovely KK has a difficult Social problem. 
A big earthquake happened in his area. 
N(2N2000)N(2≤N≤2000) cities have been implicated. All the roads between them are destroyed. 
Now KK was commissioned to rebuild these roads. 
However, after investigation,KK found that some roads are too damaged to rebuild. 
Therefore, there are only  M(0M15000)M(0≤M≤15000) roads can be rebuilt. 
KK needs to make sure that there is a way between any two cities, and KK wants to rebuild roads as few as possible. 
With rebuilding minimal number of roads, he also wants to minimize the difference between the price of the most expensive road been built and the cheapest one.
InputThe first line of the input file contains an integer  T(1T10)T(1≤T≤10), which indicates the number of test cases. 

For each test case,The first line includes two integers  N(2N2000)N(2≤N≤2000)M(0M15000)M(0≤M≤15000)

The next  MM lines include three integers  a,b,c(ab,1c2109)a,b,c(a≠b,1≤c≤2∗109),indicating there is a undirected edge between  aa and  bb,the cost is  cc.OutputFor each test case, output the smallest difference between the price of the most expensive road and the cheapest one.If there is no legal solution, then output -1.Sample Input
2
5 10
1 2 9384
1 3 887
1 4 2778
1 5 6916
2 3 7794
2 4 8336
2 5 5387
3 4 493
3 5 6650
4 5 1422
2 0
Sample Output
1686
-1

呃  。。 题目大意:

n个城市, m条可以修建的路, 修每条路有一个费用, 要求修建路将n个城市全部联通,并且要求最大费用减去最小费用最小。思路:依次枚举最小边进行比较。。。

克鲁斯卡尔 :

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;

struct Node{
    int a;
    int b;
    int len;
}node[15005];
int fa[2005];
int n,m;
int flag;

int found(int x) {
	if(x!=fa[x])
	fa[x] = found(fa[x]);
	return fa[x];
}

bool cmp(Node x,Node y)
{
	return x.len < y.len;
}

int kruscal(int k) {
    int maxcost = 0;
    for(int i = 0;i <= n;i++){
        fa[i] = i;
    }
    int t = 0;
    for(int i = k; i < m; i++) {
        int r1 = found(node[i].a);
        int r2 = found(node[i].b);
        if(r1 != r2) {
            fa[r1] = r2;
            t++;
            maxcost = max(maxcost,node[i].len);
        }
    }
    if(t == n-1)
    return maxcost;
	else return 0; 
}

int main() {
    int t;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        for(int i = 0; i < m; i++) {
            scanf("%d%d%d",&node[i].a,&node[i].b,&node[i].len);
        }
        sort(node,node+m,cmp);
        int ans = INF;
        flag = 1;
        for(int i = 0; i < m; i++) {
            int ans2 = kruscal(i);
            if(ans2 == 0){
                break;
            }
            ans = min(ans,ans2-node[i].len);
        }
        if(ans == INF)
		cout<<-1<<endl;
		else 
		cout<<ans<<endl; 
    }
    return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值