CF1027D Mouse Hunt

starseven

2020-06-05 20:08:16

Solution

[同步于我的博客](https://www.cnblogs.com/starseven/p/13052121.html) [题目链接](https://codeforces.com/problemset/problem/1027/D) [luogu链接](https://www.luogu.com.cn/problem/CF1027D) 这道题的简略题意是: 有一个$n$个点,$n$条边的有向图(可能有自环和重边),叫我们以最小代价选取一些点,使得无论从哪个点出发都要经过这些点。 思路: 因为有n个点,n条边,所以说我们可以知道一定至少有一个环。 而对于一条链来说,这条链必然要通向一个环! 所以我们就可以先进行topo排序,将所有的链删去,然后进行dfs来寻找环内的最大值! $$ Talk \;is\;cheap,\;show\;the\;code\;!$$ ```cpp #include<cstdio> #include<iostream> #define ri register int #define Starseven main using namespace std; const int N=2e5+20; int n,m,cost[N],ans=0,k,to[N],du[N]; bool vis[N]; void Topo(int x){ vis[x]=true; du[to[x]]--; if(!du[to[x]]) Topo(to[x]); } int Dfs(int x){ vis[x]=true; if(!vis[to[x]]) return min(Dfs(to[x]),cost[x]); else return cost[x]; } int Starseven(void){ cin>>n; for(ri i=1;i<=n;i++) cin>>cost[i]; for(ri i=1;i<=n;i++){ int x;cin>>x; to[i]=x,du[x]++; } for(ri i=1;i<=n;i++) if(!du[i]&&!vis[i]) Topo(i); for(ri i=1;i<=n;i++) if(!vis[i]) ans+=Dfs(i); cout<<ans<<endl; return 0; } ```