USACO22OPEN-Silver B
前言(Front talk)
网址(Website)
题目(Problem)
- 如果伙伴
已经离开了她的农场,则伙伴 仍然留在她的农场。 - 否则,伙伴
离开她的农场去访问伙伴 的农场。这次访问会产生快乐的哞叫 次( )。
输入格式(Input)
输出格式(Output)
样例(Example)
样例输入
4
2 10
3 20
4 30
1 40
样例输出
90
提示(Notice)
样例解释
如果
- 伙伴
访问伙伴 的农场,产生 次哞叫。 - 伙伴
看到伙伴 已经离开了农场,所以无事发生。 - 伙伴
访问伙伴 的农场,又产生 次哞叫。 - 伙伴
看到伙伴 已经离开了农场,所以无事发生。
这样总计得到了
另一方面,如果
- 伙伴
访问伙伴 的农场,产生 次哞叫。 - 伙伴
访问伙伴 的农场,产生 次哞叫。 - 伙伴
访问伙伴 的农场,产生 次哞叫。 - 伙伴
看到伙伴 已经离开了农场,所以无事发生。
这样总计得到了
题解(Solution)
代码(Code)
我的代码(拓扑排序)
#include<bits/stdc++.h>
#include<vector>
#include<queue>
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
#define P pair<int,int>
#define int long long
inline int input(){int x;return cin>>x,x;}
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 101234;
int n,ans,inn[N];
vector<P> ft[N];
bitset<N> vst;
inline int dfs(int x){
vst[x]=true;
int minn=inf;for(auto p:ft[x]){
int y=p.first,v=p.second;
minn=min(minn,v);
// printf("%d %d %d min=%d\n",x,y,v,minn);
if(vst[y]) continue;
minn=min(dfs(y),minn);
}return minn;
}
queue<int> q;
void Tuopu(){
For(x,1,n) if(!inn[x]) q.push(x);
while(q.size()){
int x=q.front();q.pop();
vst[x]=true;
for(auto p:ft[x]){
int y=p.first;
if(--inn[y]==0ll) q.push(y);
}
}For(x,1,n) if(!vst[x]) ans-=dfs(x);
return;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string str("visits");
freopen((str+".in").c_str(),"r",stdin);
freopen((str+".out").c_str(),"w",stdout);
cin>>n;For(x,1,n){
int y=input(),v=input();
ft[x].push_back({y,v});
inn[y]++;ans+=v;
}Tuopu();
cout<<ans<<'\n';
return 0;
}
cx的代码(最小生成树)
#include <bits/stdc++.h>
using namespace std;
#define N 100010
using ll = long long;
int a[N];
ll v[N];
int n;
int fa[N];
int getfa(int v) {
return v == fa[v] ? v : fa[v] = getfa(fa[v]);
}
int p[N];
ll ans;
int main() {
freopen("visits.in", "r", stdin);
freopen("visits.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 1; i <= n; ++i) {
scanf("%d%lld", a + i, v + i);
p[i] = i;
}
sort(p + 1, p + n + 1, [&](int x, int y){return v[x] > v[y];});
for (int i = 1; i <= n; ++i) {
int x = getfa(p[i]), y = getfa(a[p[i]]);
if (x != y) {
ans += v[p[i]];
fa[x] = y;
}
}
printf("%lld\n", ans);
return 0;
}