TZOJ8099: Visits(USACO2022、并查集、最小生成树)

TZOJ8099: Visits

题目传送门

描述

Each of Bessie’s N (2≤N≤10^5) bovine buddies (conveniently labeled 1…N) owns her own farm. For each 1≤i≤N, buddy i wants to visit buddy ai (ai≠i).

Given a permutation (p1,p2,…,pN) of 1…N, the visits occur as follows.

For each i from 1 up to N:

● If buddy Api has already departed her farm, then buddy pi remains at her own farm.

● Otherwise, buddy pi departs her farm to visit buddy Api’s farm. This visit results in a joyful “moo” being uttered Vpi times (0≤Vpi≤10^9).

Compute the maximum possible number of moos after all visits, over all possible permutations p.

输入

The first line contains N.

For each 1≤i≤N, the i+1-st line contains two space-separated integers ai and vi.

输出

A single integer denoting the answer.

样例输入
4
2 10
3 20
4 30
1 40
样例输出
90
提示

If p=(1,4,3,2) then

● Buddy 1 visits buddy 2’s farm, resulting in 10 moos.

● Buddy 4 sees that buddy 1 has already departed, so nothing happens.

● Buddy 3 visits buddy 4’s farm, adding 30 moos.

● Buddy 2 sees that buddy 3 has already departed, so nothing happens.

This gives a total of 10+30=40 moos.

On the other hand, if p=(2,3,4,1) then

● Buddy 2 visits buddy 3’s farm, causing 20 moos.

● Buddy 3 visits buddy 4’s farm, causing 30 moos.

● Buddy 4 visits buddy 1’s farm, causing 40 moos.

● Buddy 1 sees that buddy 2 has already departed, so nothing happens.

This gives 20+30+40=90 total moos. It can be shown that this is the maximum possible amount after all visits, over all permutations p.

解题思路

题目给出1到N的点所能到达的点,还有得到的价值,并且从一点出发后该点被标记而不能再被其他点走到,问我们能否找到一个1到N的走法的排列使得到的价值最大。那么根据样例画图得到样例
我们发现2,3,4,1走通之后,1不能再走到2了,此时我们连了n - 1条边使各点连通,而各点连通后有了最大值,就大胆猜测是最小生成树了(从价值大的边开始),这是它的一种性质。

代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define IOS ios::sync_with_stdio(0), cin.tie(0)
const ll N = 1e5 * 1 + 5;
inline ll read() {
    ll x=0,f=1;char c=getchar();
    while (!isdigit(c)) {if(c=='-')f=-1;c=getchar();}
    while (isdigit(c)) {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    return x*f;
}
struct node {
    ll x, y, z;
    friend bool operator<(node a, node b) {
        return a.z > b.z;
    }
}e[N];
ll n, f[N];
ll find(ll v) {return v == f[v] ? v : f[v] = find(f[v]);}
void solve() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        f[i] = i;
        ll x, y, z; cin >> y >> z; x = i;
        e[i]= {x, y, z};
    }
    sort(e + 1, e + n + 1);
    ll ans = 0;
    for (int i = 1; i <= n; ++i) {
        ll x = find(e[i].x), y = find(e[i].y);
        if(x != y) {
            f[x] = y;
            ans += e[i].z;
        }
    }
    cout << ans << endl;
}

int main( ){
    IOS;
//    ll t; cin >> t;
    ll t = 1;
    while (t--) solve();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值