Codeforces B. Mouse Hunt(强连通分解缩点)
题目描述:
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(强连通分解缩点)的更多相关文章
- Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)
<题目链接> 题目大意: 有n个房间,每个房间都会有一只老鼠.处于第i个房间的老鼠可以逃窜到第ai个房间中.现在要清理掉所有的老鼠,而在第i个房间中防止老鼠夹的花费是ci,问你消灭掉所有老 ...
- Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )
题意 : 给出 n 个点,每个点有一个维护时间 a[i].m 个条件,每个条件有2个点(x,y)且 a[x] != a[y].选择最少的 k (最少一个)个点,使其值加1后,m个条件仍成立. 分析 : ...
- 【Edu49 1027D】 Mouse Hunt DFS 环
1027D. Mouse Hunt:http://codeforces.com/contest/1027/problem/D 题意: 有n个房间,每个房间放置捕鼠器的费用是不同的,已知老鼠在一个房间x ...
- POJ1236Network of Schools[强连通分量|缩点]
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16571 Accepted: 65 ...
- POJ1236Network of Schools(强连通分量 + 缩点)
题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...
- HD2767Proving Equivalences(有向图强连通分量+缩点)
题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...
- UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)
题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...
- ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)
题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...
- POJ2553 The Bottom of a Graph(强连通分量+缩点)
题目是问,一个有向图有多少个点v满足∀w∈V:(v→w)⇒(w→v). 把图的强连通分量缩点,那么答案显然就是所有出度为0的点. 用Tarjan找强连通分量: #include<cstdio&g ...
随机推荐
- 使用pprof调试go程序
使用pprof调试go程序 pprof可以用来调试go程序,在go中有两个库可以使用,1. net/http/pprof 2. runtime/pprof 方法1 - net/http/pprof 测 ...
- shell 编写脚本批量Ping IP
服务器总是一下子买了很多的段的ip.通过绑定后,也不知道这些ip是否绑定成功,所以就写了一个shell脚本,把ip输好,批量ping一下,看是不是都能ping通. 脚本如下: 此外.还有一个ip文件, ...
- PHP变量回收
PHP变量回收1 离开页面2 unset
- php imagick添加文字和图片的方法
Imagick添加文字和图片的方法<pre><?php $image = new Imagick(); $image->readImage("/home/www/wo ...
- cisco ap客户端无规律掉线
设备 cisco air-ct2504-50-k9 cisco air-ap1832I-H-k9 首先根据这个帖子 https://community.cisco.com/t5/other-wirel ...
- 【转帖】HBase简介(梳理知识)
HBase简介(梳理知识) https://www.cnblogs.com/muhongxin/p/9471445.html 一. 简介 hbase是bigtable的开源山寨版本.是建立的hdf ...
- Linux下Ngnix的安装与配置
由于我的博客项目在8084端口,需要Nginx来转发一下端口,记录一下安装过程和踩过的小坑. 一.下载 wget http://nginx.org/download/nginx-1.12.2.tar. ...
- Feign调用时读取超时(Read timed out executing GET)解决
解决方式(很多人比较关注,所以放在最前面): 因为Feign调用默认的超时时间为一分钟,一分钟接口不能返回就会抛出异常,所以在服务端的yml文件中增加如下配置即可解决: # feign调用超时时间配置 ...
- ajax中如何使用全局变量?
在ajax中一般都是采取默认的异步请求,但是有时候参数是需要做到全局通用,这时候发起同步请求. 如下: $.ajax({ type:"post", url:"url路径& ...
- STVD生成hex,bin,显示ram&flash的使用情况
前言: 虽然stvd免费,但使用起来并不令人满意,不能自动补全,界面丑陋,设置繁琐,最难受的是不会自动输出ram和flash的使用情况.当然方法还是有的,下面就讲讲我是怎么实现的.个人水平有限,如有错 ...