Graph(最小生成树+克鲁斯卡尔)
题目描述
小 Y 又开始了一段旅途。
这次,他要经过一个图,从1号点到达n号点,每个点设有休息站。
小 Y 计划用最多k天走完全程,除第k天外,每一天小 Y 都必须在休息站过夜。所以,一段路必须在同一天走完。
小 Y 的体力有限,他希望走的路程最大的一天中走的路尽可能少,请求出这个最小值。
输入
第一行三个整数n、m、k表示图的顶点数、边数、天数。
从第二行开始,之后的 m 行,每行三个整数 ui、vi、wi表示从 ui和 vi间有一条双向道路,长度为wi。
输出
一行一个正整数,如果小 Y 能走完全程,输出走的路程最大的一天中走的路程最小值,否则输出−1。
样例输入
3 2 4 3 2 4 1 2 1
样例输出
思路:克鲁斯卡尔算法模板题,套模板就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef struct Node
{
ll a = 0;
ll b = 0;
ll dis = 0;
} Node;
ll find(ll set[], ll x)
{
if(set[x] == x)
return x;
else
return find(set, set[x]);
}
void merge(ll i, ll j, ll rank[], ll set[])//按秩合并
{
ll x = find(set, i); ll y = find(set, j);
if(rank[x] <= rank[y])
set[x] = y;
else
set[y] = x;
if(rank[x] == rank[y] && x != y)
rank[y]++;
}
bool cmp(Node a, Node b)
{
return a.dis < b.dis;
}
int main()
{
ll n = 0; ll m = 0; ll day = 0;
cin >> n >> m >> day;
vector<Node> node;
ll set[n + 1] = { 0 };
ll rank[n + 1] = { 0 };
for(int i = 0; i <= n; ++i)
{
set[i] = i;
rank[i] = 1;
}
for(ll i = 0; i < m; ++i)
{
Node temp;
cin >> temp.a >> temp.b >> temp.dis;
node.push_back(temp);
}
sort(node.begin(), node.end(), cmp);
long long res = 0;
int flag = 0;
for(int i = 0; i < node.size(); ++i)
{
ll a = node[i].a; ll b = node[i].b; ll dis = node[i].dis;
a = find(set, a); b = find(set, b);
if(a != b)
{
merge(a, b, rank, set);
res = dis;
}
if(find(set, 1) == find(set, n))
{
flag = 1;
break;
}
}
if(flag == 0)
cout << -1 << endl;
else
cout << res << endl;
return 0;
}