题目描述:

Mouse Hunt

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Medicine faculty of Berland State University has just finished their admission campaign. As usual, about 80%of applicants are girls and majority of them are going to live in the university dormitory for the next

4(hopefully) years.

The dormitory consists of n rooms and a single mouse! Girls decided to set mouse traps in some rooms to get rid of the horrible monster. Setting a trap in room number costs \(c_i\) burles. Rooms are numbered from 1 to n

Mouse doesn't sit in place all the time, it constantly runs. If it is in room i in second then it will run to room \(a_i\) without visiting any other rooms inbetween (i=\(a_i\)means that mouse won't leave room i) It 's second 0 in the start.If the mouse is in some room with a mouse trap in it, then the mouse get caught into this trap.

That would have been so easy if the girls actually knew where the mouse at. Unfortunately, that's not the case, mouse can be in any room from 1 to at second 0

What it the minimal total amount of burles girls can spend to set the traps in order to guarantee that the mouse will eventually be caught no matter the room it started from?

Input

The first line contains as single integers n(\(1\leq n\leq 2*10^5\)) — the number of rooms in the dormitory.

The second line contains nintegers \(c_1,c_2,...,c_n\) (1≤\(c_i\)≤\(10^4\))is the cost of setting the trap in room number i

The third line contains nintegers \(a_1,a_2,...,a_n\)(1≤\(a_i\)n) is the room the mouse will run to the next second after being in room i

Output

Print a single integer — the minimal total amount of burles girls can spend to set the traps in order to guarantee that the mouse will eventually be caught no matter the room it started from.

Examples

Input

Copy

51 2 3 2 101 3 4 3 3

Output

Copy

3

Input

Copy

41 10 2 102 4 2 2

Output

Copy

10

Input

Copy

71 1 1 1 1 1 12 2 2 3 6 7 6

Output

Copy

2

Note

In the first example it is enough to set mouse trap in rooms 1 and 4. If mouse starts in room 1.then it gets caught immideately. If mouse starts in any other room then it eventually comes to room 4.

In the second example it is enough to set mouse trap in room 2. If mouse starts in room then it gets caught immideately. If mouse starts in any other room then it runs to room 2 in second 1.

Here are the paths of the mouse from different starts from the third example:

1→2→2→…;

2→2→…;

3→2→2→…;

4→3→2→2→…;

5→6→7→6→…;

6→7→6→…;

7→6→7→…;

So it's enough to set traps in rooms 2 and 6.

思路:

题目是说各一个数组a,其中i指向ai,也就是给了一个图,这个图是老鼠行程,根据这个图我们可以看到老鼠最终会在某个点停下,要么会一直的兜圈子。要求不管老鼠一开始在哪个房间,以某种代价最小的方式放置捕鼠夹,使得最后定能捕住老鼠。求这个最小代价。

我们发现只要在老鼠停下来的地方或者环上代价最小的一个地方放置捕鼠夹就能捕住老鼠。其实这道题就可以看成是图的强连通分解,通过tarjan算法求这个图有多少个强连通块,最后求出的强连通块再进行缩点,把一个强连通块看成一个点,并存储这个强连通块上的最小代价。最后要求的点是出度为0的点,为什么?因为出度为零的点就是最后老鼠停下来的点和环(已经缩点)。

需要注意的是缩点的一些细节,记录好强连通块的数目,每个强连通块建立对应的最小代价数组,遍历一遍点求出每个强连通块对应的最小代价,和每个强连通块的出度(只要有边相连的两个点不在一个强连通块上出度就减小一。最后遍历每个强连通块,求出出度为零的强连通块的最小代价和。

代码:

#include <iostream>
#include <cstdio>
#include <stack>
#define max_n 200005
#define INF 0x3f3f3f3f
using namespace std;
//题目数据
int a[max_n];
int c[max_n];
int n;
//链式前向星
int cnt = 0;
int head[max_n];
struct
{
int v;
int next;
}e[max_n<<1];
void add(int u,int v)
{
++cnt;
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt;
}
//读入优化
template<typename T>
inline void read(T& x)
{
x = 0;int f = 0;char ch = getchar();
while(ch<'0'||ch>'9') {f |= (ch=='-');ch = getchar();}
while(ch>='0'&&ch<='9') {x = x*10+ch-'0';ch = getchar();}
x = f?-x:x;
}
//tarjan算法
int Bcnt = 0;
int idx = 0;
int dfn[max_n];
int low[max_n];
int instack[max_n];
int Belong[max_n];
stack<int> s;
int Deg[max_n];
int cost[max_n];
void tarjan(int u)
{
dfn[u] = low[u] = ++idx;
s.push(u);
instack[u] = 1;
int v;
for(int i = head[u];i;i=e[i].next)
{
v = e[i].v;
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u],low[v]);
}
else if(instack[v])
{
low[u] = min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
Bcnt++;
do
{
v = s.top();
s.pop();
instack[v] = 0;
Belong[v] = Bcnt;
}while(u!=v);
}
}
void solve()
{
for(int i = 1;i<=n;i++)
{
cout << "d " << dfn[i] << " l " << low[i] << endl;
}
cout << "共有 " << Bcnt << " 个连通分量" << endl;
for(int i = 1;i<=Bcnt;i++)
{
cout << "第 " << i << "个 " << endl;
for(int j = 1;j<=n;j++)
{
if(Belong[j]==i)
{
cout << j << " ";
}
}
cout << endl;
}
}
int main()
{
read(n);
for(int i = 1;i<=n;i++)
{
read(c[i]);
}
for(int i = 1;i<=n;i++)
{
read(a[i]);
add(i,a[i]);//建边
}
for(int i = 1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
//solve();
//缩点
for(int i = 1;i<=Bcnt;i++)
{
cost[i] = INF;
}
for(int i = 1;i<=n;i++)
{
cost[Belong[i]] = min(cost[Belong[i]],c[i]);//求出每个强连通分量的最小cost
}
for(int i = 1;i<=n;i++)
{
if(Belong[i]!=Belong[a[i]])
{
Deg[Belong[i]]++;//如果连个相连的点不在一个强连通分量里面,那么他所属的强连通分量的出度加一
}
}
/*for(int i =1;i<=n;i++)
{
cout << "Deg " << i << " : " << Deg[i] << endl;
}*/
int ans = 0;
for(int i = 1;i<=Bcnt;i++) //遍历所有的强连通分量
{
//cout << "deg " << i << ":" << Deg[i] << endl;
if(Deg[i]==0)
{
ans += cost[i];//如果该连通分量的出度为一,则比在这个连通分量上放一个捕鼠夹
}
}
cout << ans << endl;
return 0;
}

参考文章:

悠悠呦~,Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集),https://www.cnblogs.com/00isok/p/10394721.html

Codeforces B. Mouse Hunt(强连通分解缩点)的更多相关文章

  1. Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)

    <题目链接> 题目大意: 有n个房间,每个房间都会有一只老鼠.处于第i个房间的老鼠可以逃窜到第ai个房间中.现在要清理掉所有的老鼠,而在第i个房间中防止老鼠夹的花费是ci,问你消灭掉所有老 ...

  2. Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )

    题意 : 给出 n 个点,每个点有一个维护时间 a[i].m 个条件,每个条件有2个点(x,y)且 a[x] != a[y].选择最少的 k (最少一个)个点,使其值加1后,m个条件仍成立. 分析 : ...

  3. 【Edu49 1027D】 Mouse Hunt DFS 环

    1027D. Mouse Hunt:http://codeforces.com/contest/1027/problem/D 题意: 有n个房间,每个房间放置捕鼠器的费用是不同的,已知老鼠在一个房间x ...

  4. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  5. POJ1236Network of Schools(强连通分量 + 缩点)

    题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...

  6. HD2767Proving Equivalences(有向图强连通分量+缩点)

    题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...

  7. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...

  8. ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)

    题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...

  9. POJ2553 The Bottom of a Graph(强连通分量+缩点)

    题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: #include<cstdio&g ...

随机推荐

  1. Javacript Remove Elements from Array

    參考自: https://love2dev.com/blog/javascript-remove-from-array/ 1. Removing Elements from End of Array ...

  2. Zero-shot User Intent Detection via Capsule Neural Networks

    Architecture                 SemanticCaps 通过Bi-LSTM表征得到的隐层向量经过multi-head后可以得到R个表征             Detect ...

  3. Java中参数始终是按值传递

    Java中参数始终是按值传递. public class Main { public static void main(String[] args) { int x = 5; change(x); S ...

  4. java中通过Adb判断PC是否连接了移动设备

    最近用到PC端和移动端通过USB连接传输数据的方式,于是总在使用Adb命令,为了逻辑的严谨和代码容错,想在传输数据的之前,PC和移动端先建立一次会话,防止移动端还未连接就直接传输数据会报错,找了很久并 ...

  5. Python使用队列实现Josephus问题

    Josephus问题,在这个古老的问题中,N个深陷绝境的人一致同意通过以下方式减少生存的人数.他们围坐一圈(位置记为0~N-1)并从第一个人报数,报到M的人会被杀死, 知道最后一个人留下来.传说中Jo ...

  6. springboot集成drools的方式一

    springboot集成drools的方式一(spring-drools.xml) 本文springboot采用1.5.1.RELEASE版本,drools采用的6.5.0.Final,一共会讲三种方 ...

  7. java中常见关键字的介绍

    Java中类,属性,方法修饰符 public 公共访问权限,不但在本应用中可以放问,其他应用也可以访问.接口中的方法默认都是public的 protected 被protected修改的:可以被本类, ...

  8. 2019 快乐阳光java面试笔试题 (含面试题解析)

    本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.快乐阳光等公司offer,岗位是Java后端开发,最终选择去了快乐阳光. 面试了很多家公司,感觉大部分公司考察的点 ...

  9. JAVA案例练习: 去除ArrayList中重复的字符串(字符串内容相同),去除重复的对象

    package com.yqw.list; import java.util.ArrayList;import java.util.Iterator; public class Demo_ArrayL ...

  10. IDEA中调试时F8,F7快捷键失效

    idea中调试时F8,F7快捷键失效 原因:相关软件的快捷键占用了F8,F7,如我的有道词典占用F8了这个快捷键,导致idea调试时不能使用F8,改变有道词典的快捷键即可.