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