51 nod 1456 小K的技术(强连通 + 并查集)
1456 小K的技术
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市,标记为1到n。
由于小K的研究,我们最终能过在两个城市之间建立传输管道,一个传输管道能单向连接两个城市,即,一个从城市x到城市y的传输管道不能被用于从城市y传输到城市x。在每个城市之间的运输系统已经建立完善,因此,如果从城市x到城市y的管道和从城市y到城市z的管道都被已经被建立,人们能够立即从x到z。
小K也研究了国家政治,他认为在这m对城市(ai, bi) (1 ≤ i ≤ m)之间的传输尤其重要。他正在计划为每个重要城市对(ai, bi)建立传输管道,通过使用一个或多个传输管道,我们可以从城市ai到城市bi(但不需要从城市bi到城市ai)。我们要找出必须建立的传输管道的最小数。至今,还没有传输管道被建立,在每个城市之间也没有其他有效的传输方式。
对于第一个样例,其中一条最优路径如下图:

第一行是两个以空格隔开的整数n和m(2 ≤ n ≤10^5 , 1 ≤ m ≤ 10^5 ),分别表示在苏塞克王国中的城市数和重要城市对的数。
之后m行描述重要城市对,第i行 (1 ≤ i ≤ m)包含两个以空格隔开的整数ai和bi(1 ≤ ai, bi ≤ n, ai ≠ bi),表示必须能通过一条或两条传输管道从城市ai到城市bi(但不需要从城市bi到城市ai),我们保证所有的城市对(ai, bi)是唯一的。
输出满足小K目的所需要的传输管道的最小数。
4 5
1 2
1 3
1 4
2 3
2 4
3
/*
51 nod 1456 小K的技术(强连通 + 并查集) problem:
给你n个城市和m次操作. 每次a,b表示两个城市a->b之间应该连通. 而添加的管道是单向的,求最少需要多少的
管道才能满足要求. solve:
在一个联通块里面,可以发现最糟糕的情况就是没有环,那么n-1条就能够满足条件.
但是如果存在环,这样的话n个点需要围成一个圈,所以需要n条管道. 所以可以用tarjan算法来判断一下强连通就好了,只要存在强连通分支,则说明当前联通块需要n个管道.
然后用并查集来记录每个联通块中点的数量.
- - 一直WR. 结果发现如果联通块a和联通块b被一个单向边连接. 我在搜索a的时候并不能到达b,判断出现了一些问题,
这里注意一下就好了 hhh-2016/09/08-21:11:22
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define scanfd(a) scanf("%lf",&a)
#define key_val ch[ch[root][1]][0]
#define eps 1e-7
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1000000007;
const int maxn = 300050;
const double PI = acos(-1.0);
const int limit = 33;
int pre[maxn];
int cnt[maxn];
template<class T> void read(T&num)
{
char CH;
bool F=false;
for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar());
for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p)
{
if(!p)
{
puts("0");
return;
}
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} int fin(int x)
{
if(pre[x] == x) return x;
return pre[x] = fin(pre[x]);
} void unio(int a,int b)
{
int ta= fin(a);
int tb = fin(b);
if(ta == tb)
return ;
pre[tb] = ta;
cnt[ta] += cnt[tb];
} int tot = 0;
int index,top,scc;
int head[maxn];
int low[maxn],dfn[maxn],Stack[maxn],Belong[maxn],num[maxn];
bool Instack[maxn];
ll ans[maxn];
struct node
{
int u,v,nex;
} edge[maxn]; void add_edge(int u,int v)
{
edge[tot].u = u,edge[tot].v = v,edge[tot].nex = head[u],head[u] = tot++;
} void init()
{
tot = 0;
for(int i = 1; i <= maxn-50; i++)
{
ans[i] = 0;
head[i] = -1,pre[i] = i;
num[i] = dfn[i] = 0;
Instack[i] = false;
cnt[i] = 1;
}
index = top = scc = 0;
}
int flag;
//ll cnt;
void Tarjan(int u)
{
int v;
// if(!dfn[u])
// cnt ++ ;
low[u] = dfn[u] = ++index;
Stack[top++] = u;
Instack[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].nex)
{
v = edge[i].v;
if(! dfn[v])
{
Tarjan(v);
if(low[u] > low[v])
low[u] = low[v];
}
else if(Instack[v] && low[u] > dfn[v])
low[u] = dfn[v];
}
if(low[u] == dfn[u])
{
scc ++ ;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc;
num[scc] ++ ;
if(num[scc] > 1)
flag = 1;
}
while(v != u);
}
} int main()
{
// freopen("in.txt","r",stdin);
int n,m;
int u,v; while(scanfi(n) != EOF)
{
scanfi(m);
init();
for(int i = 1; i <= m; i++)
{
read(u),read(v);
add_edge(u,v);
unio(u,v);
}
for(int i = 1; i <= n; i++)
{
if(!dfn[i])
{
flag = 0;
Tarjan(i);
int anc = fin(i);
if(ans[anc] == cnt[anc])
continue;
if(flag)
ans[anc] = cnt[anc];
else
ans[anc] = cnt[anc]-1;
}
}
ll toans = 0;
for(int i = 1;i <= n;i++)
toans += ans[i];
printf("%I64d\n",toans);
}
return 0;
}
/*
4 6
1 2
1 4
2 3
2 4
3 2
3 4 */
51 nod 1456 小K的技术(强连通 + 并查集)的更多相关文章
- K:Union-Find(并查集)算法
相关介绍: 并查集的相关算法,是我见过的,最为之有趣的算法之一.并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.其相关的实现代码较为简短,实现思想也 ...
- 洛谷P2498 [SDOI2012]拯救小云公主 【二分 + 并查集】
题目 英雄又即将踏上拯救公主的道路-- 这次的拯救目标是--爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意识到自己还是等级1 ...
- 【bzoj3007】拯救小云公主 二分+对偶图+并查集
题目描述 英雄又即将踏上拯救公主的道路…… 这次的拯救目标是——爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意识到自己还是等 ...
- HihoCoder 1638 : 小Hi的天平 (2-sat+并查集)
描述 小Hi给小Ho邮寄了一个天平.收到天平后,小Ho想知道天平在运输过程中是否损坏,为此它准备了A类物品和B类物品共n个(可能只有A类物品,也可能只有B类物品),但无法确定一个物品是哪一类.A类物品 ...
- 51 NOD 1685 第K大区间2 二分+BIT
题目描述: 定义一个长度为奇数的区间的值为其所包含的的元素的中位数. 现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. 样例解释: [l,r]表示区间的值 [1]:3 [2]:1 ...
- 51 nod 1105 第K大的数
1105 第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 数组A和数组B,里面都有n个整数.数组C共有n^2个整数,分别是A[0] * ...
- Going from u to v or from v to u?_POJ2762强连通+并查集缩点+拓扑排序
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Description I ...
- bzoj3007: 拯救小云公主(二分+并查集)
挺水的题...好多题解说是对偶图,其实感觉不能算严格意义上的对偶图吧QAQ 先二分答案r,然后以boss为中心半径为r的圆不能走,求能否从左下走到右上. 不能从左下走到右上,说明这堆圆把图隔开了,于是 ...
- 第46届ICPC澳门站 K - Link-Cut Tree // 贪心 + 并查集 + DFS
原题链接:K-Link-Cut Tree_第46屆ICPC 東亞洲區域賽(澳門)(正式賽) (nowcoder.com) 题意: 要求一个边权值总和最小的环,并从小到大输出边权值(2的次幂):若不存在 ...
随机推荐
- python 继承基础
class annamal: def chi(self): print(self.name + '吃') def he(self): print(self.name + '喝') class dog( ...
- JAVA和Android的回调机制
本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273),请尊重他人的辛勤劳动成果,谢谢 以 前不理解什么叫回 ...
- Java面试题合集(一)
接下来几篇文章准备系统整理一下有关Java的面试题,分为基础篇,javaweb篇,框架篇,数据库篇,多线程篇,并发篇,算法篇等等,陆续更新中. 其他方面如前端后端等等的面试题也在整理中,都会有的. 所 ...
- wpf研究之道——datagrid控件分页
这是我们的datagrid分页效果图,有上一页,下一页,可以跳到任何一页.当页码比较多的时候,只显示几页,其余用点点,界面实现如下: <!--分页--> <StackPanel Or ...
- Python内置函数(36)——reversed
英文文档: reversed(seq) Return a reverse iterator. seq must be an object which has a __reversed__() meth ...
- sql优化基础篇
优化的步骤: 0.先sql运行看看是否真的很慢,注意设置SQL_NO_CACHE 1.where条件单表查,锁定最小返回记录表.这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始 ...
- Angular 学习笔记 ( CDK - Accessibility )
@angular/ckd 是 ng 对于 ui 组建的基础架构. 是由 material 团队开发与维护的, 之所以会有 cdk 看样子是因为在开发 material 的时候随便抽象一个层次出来给大家 ...
- api-gateway实践(01)服务网关 - 原型功能
一.服务注册 1.增加组:LsqGrpA 2.增加版本:LsqVerA 3.增加api:LsqApiA 3.1.基本信息 3.2.前端定义 3.3.后端定义 二.服务上线和服务授权 1.服务上线 2. ...
- bootstrap 菜单之手风琴效果
自己用bootstrap搭了个项目,纯属娱乐....为了检验学习bootstrap之成果. 效果如图: 一.搭建中发现一问题,因为以前测试都是写的html页面,这次用了母版页,点击页面的之后,页面会刷 ...
- 赛码网算法: 上台阶 ( python3实现 、c实现)
上台阶 题目描述 有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法?注:规定从一级到一级有0种走法. 输入输入数据首先包含一个整数n(1<=n<=1 ...