Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)
<题目链接>
题目大意:
有n个房间,每个房间都会有一只老鼠。处于第i个房间的老鼠可以逃窜到第ai个房间中。现在要清理掉所有的老鼠,而在第i个房间中防止老鼠夹的花费是ci,问你消灭掉所有老鼠的最少花费。
解题分析:
首先就是要注意老鼠的逃生路线为强连通分量的情况,毫无疑问,这种情况就是在那个强连通分量中的代价最小的房间安装老鼠夹(因为根据老鼠的流通性,只需要在连通分量中安装一个老鼠夹就能捕获所有的老鼠),所以我们先用Tarjan对这些房间进行缩点。然后我们只需要将那些出度为0的强连通分量的代价相加就行(强连通分量的代价=其中任意点的最小代价),因为出度为0的强连通分量一定要消除本身的老鼠,并且根据老鼠的流通性,其它出度不为0的老鼠一定也会到达这些出度为0的连通分量中。
 #include <bits/stdc++.h>
 using namespace std;
 const int INF =0x3f3f3f3f;
 #define N int(2e5+7)
 #define rep(i,s,t) for(int i=s;i<=t;i++)
 #define srep(i,s,t) for(int i=s;i<t;i++)
 #define clr(a,b) memset(a,b,sizeof(a))
 int n,top,ans,tot,scc;
 int outdeg[N],to[N],stk[N],instk[N],bel[N],dfn[N],low[N],cost[N],val[N];
 template<typename T>       //读入优化
 inline T read(T&x){
     x=;;char ch=getchar();
     ') f|=(ch=='-'),ch=getchar();
     +ch-',ch=getchar();
     return x=f?-x:x;
 }
 void Tarjan(int u){
     dfn[u]=low[u]=++tot;
     stk[++top]=u;instk[u]=;
     int v=to[u];
     if(!dfn[v]){
         Tarjan(v);
         low[u]=min(low[u],low[v]);
     }else if(instk[v])low[u]=min(low[u],dfn[v]);
     if(dfn[u]==low[u]){
         ++scc;
         while(true){
             int v=stk[top--];
             bel[v]=scc;
             if(u==v)break;
         }
     }
 }
 int main(){
     read(n);
     rep(i,,n)read(val[i]);
     rep(u,,n){
         int v;read(v);to[u]=v;
     }
     rep(i,,n) if(!dfn[i]){     //Tarjan缩点
         Tarjan(i);
     }
     rep(i,,scc)cost[i]=INF;
     rep(i,,n)cost[bel[i]]=min(cost[bel[i]],val[i]);   //cost[i]为每个强连通分量中花费最少的点
     rep(u,,n){
         int v=to[u];
         if(bel[u]!=bel[v])outdeg[bel[u]]++;   //标记每个强连通分量的出度
     }
     rep(i,,scc)if(!outdeg[i])ans+=cost[i];   //出度为0的点一定要安装(因为至少要消灭这些点本来的老鼠),并且只用安装出度为0的点,因为老鼠具有传递性,最终所有老鼠一定会经过这些出度为0的点
     printf("%d\n",ans);
 }
另一种做法,用并查集判环,DFS找环上的最小代价:
 #include<bits/stdc++.h>
 using namespace std;
 ;
 int to[N], val[N], pre[N], x[N];
 int find(int x){
     return x==pre[x]?x:pre[x]=find(pre[x]);
 }
 int dfs(int x, int root){
     if(x==root) return val[x];   //如果是自环,直接返回本身
     return min(dfs(to[x], root), val[x]);    //寻找环上权值最小的点
 }
 int main(){
     int n;scanf("%d", &n);
     ;i<=n;i++)scanf("%d", &val[i]), pre[i] = i;
     ;i<=n;i++)scanf("%d", &to[i]);
     ;i<=n;i++){     //并查集判独立的连通块(判环或者判独立的点)
         ;    //如果这个点存在环
         else pre[find(to[i])] = find(i);
     }
     ;
     ;i<=n;i++) if(x[i])ans+=dfs(to[i],i);
     printf("%d\n",ans);
 }
2019-02-18
Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)的更多相关文章
- Codeforces B. Mouse Hunt(强连通分解缩点)
		
题目描述: Mouse Hunt time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
 - CodeForces - 455C Civilization (dfs+并查集)
		
http://codeforces.com/problemset/problem/455/C 题意 n个结点的森林,初始有m条边,现在有两种操作,1.查询x所在联通块的最长路径并输出:2.将结点x和y ...
 - 51nod 1456【强连通,缩点,并查集】
		
话说这道题的机遇是看到了http://blog.csdn.net/u010885899/article/details/50611895很有意思:然后就去补了这题 题意: 建最少的边使得给出的点相连. ...
 - DFS/并查集 Codeforces Round #286 (Div. 2) B - Mr. Kitayuta's Colorful Graph
		
题目传送门 /* 题意:两点之间有不同颜色的线连通,问两点间单一颜色连通的路径有几条 DFS:暴力每个颜色,以u走到v为结束标志,累加条数 注意:无向图 */ #include <cstdio& ...
 - Codeforces 745C:Hongcow Builds A Nation(并查集)
		
http://codeforces.com/problemset/problem/744/A 题意:在一个图里面有n个点m条边,还有k个点是受限制的,即不能从一个受限制的点走到另外一个受限制的点(有路 ...
 - Codeforces Educational Codeforces Round 5 C. The Labyrinth 带权并查集
		
C. The Labyrinth 题目连接: http://www.codeforces.com/contest/616/problem/C Description You are given a r ...
 - Codeforces Round #245 (Div. 2) B. Balls Game 并查集
		
B. Balls Game Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/430/problem ...
 - Codeforces Round #345 (Div. 1) E. Clockwork Bomb 并查集
		
E. Clockwork Bomb 题目连接: http://www.codeforces.com/contest/650/problem/E Description My name is James ...
 - POJ3694 Network 边双缩点+LCA+并查集
		
辣鸡错误:把dfs和ldfs搞混...QAQ 题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数. 先把边双缩点,然后预处理出LCA的倍增数组: 然后加边时,从u往上跳 ...
 
随机推荐
- oracle_基本SQL语言
			
一:DDL数据定义语言 1:create(创建) 创建表 CREATE TABLE <table_name>( column1 DATATYPE [NOT NULL] [P ...
 - 修改Mysql5.7的root密码
			
Mysql5.7修改root密码 禁用root密码 1.修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不 ...
 - 【mongo】centos6.9安装mongo2.6.3
			
参考:http://www.haorooms.com/post/3m 注意:centos6上就不要装mongo3了,容易出错. 1. 下载 curl -O http://downloads.mongo ...
 - dbcp连接池出现的问题java.lang.AbstractMethodError: com.mysql.jdbc.Connection.isValid(I)Z
			
解决方案:mysql-connector 版本为 5.0.4 ,那么对应的 dbcp 和 pool 版本应该为 1.4 和 1.6 . 5.0.4 不应该使用 2.0 及以上版本的 dbcp 和 ...
 - Allegro PCB Design GXL (legacy) 使用slide推挤走线,走线的宽度就发生改变的原因
			
Allegro PCB Design GXL (legacy) version 16.6-2015 使用slide推挤走线,走线的宽度就会发生改变. 后来发现是因为约束管理器(Constraint M ...
 - matlab转c++代码实现(主要包含C++ std::vector,std::pair学习,包含数组与常数相乘,数组相加减,将数组拉成一维向量,图片的读入等内容)
			
MATLAB部分: xmap = repmat( linspace( -regionW/2, regionW/2, regionW), regionH, 1 );%linspace [x1,x2,N] ...
 - CSS预处理器—Sass、LESS和Stylus
			
http://www.w3cplus.com/css/css-preprocessor-sass-vs-less-stylus-2.html 一.什么是CSS预处器 CSS预处理器定义了一种新的语言, ...
 - Oracle数据库执行exp命令--报参数'log' 不允许有多个值
			
前几天设置自动备份oracle 数据库时发现一个问题,自动备份老是执行失败,后来把语句拿出来单独执行才发现是语句写的有问题,一般情况下自动备份都要自动生成日志文件,以便于我们查看备份是否正常执行.下面 ...
 - .NET C# 创建WebService服务简单的例子
			
Web service是一个基于可编程的web的应用程序,用于开发分布式的互操作的应用程序,也是一种web服务 WebService的特性有以下几点: 1.使用XML(标准通用标记语言)来作为数据交互 ...
 - 开始写博客,学习Linq(1)
			
摘自<linq实战>原文: 软件很简单.它可以归结为两件事情:代码和数据. 开发软件却并非那么简单,其中很重要的一项任务就是编写处理数据的代码. 无论选择了哪种语言,在程序开发得某个时候你 ...