Problem Description
To prove two sets A and B are equivalent, we can first prove A is a subset of B, and then prove B is a subset of A, so finally we got that these two sets are equivalent.

You are to prove N sets are equivalent, using the method above: in each step you can prove a set X is a subset of another set Y, and there are also some sets that are already proven to be subsets of some other sets.

Now you want to know the minimum steps needed to get the problem proved.
 
Input
The input file contains multiple test cases, in each case, the first line contains two integers N <= 20000 and M <= 50000.

Next M lines, each line contains two integers X, Y, means set X in a subset of set Y.
 
Output
For each case, output a single integer: the minimum steps needed.
 
Sample Input
4 0
3 2
1 2
1 3
 
Sample Output
4
2
Hint
Case 2: First prove set 2 is a subset of set 1 and then prove set 3 is a subset of set 1.
 
强联通缩点:加入几条边成强联通分量:设缩点后全部点中出度为0的点为d_1,入度为0点为d_2,则答案为max(d_1,d_2);
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<limits.h>
typedef long long LL;
using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a ) const int maxn=20000+100;
const int maxm=100000;
struct node{
int u,v;
int next;
}e[maxm];
int head[maxn],cntE;
int DFN[maxn],low[maxn];
int s[maxm],top,index,cnt;
int belong[maxn],instack[maxn];
int in[maxn],out[maxn];
int n,m;
void init()
{
top=cntE=0;
index=cnt=0;
CLEAR(DFN,0);
CLEAR(head,-1);
CLEAR(instack,0);
// CLEAR(belong,0);
}
void addedge(int u,int v)
{
e[cntE].u=u;e[cntE].v=v;
e[cntE].next=head[u];
head[u]=cntE++;
}
void Tarjan(int u)
{
DFN[u]=low[u]=++index;
instack[u]=1;
s[top++]=u;
for(int i=head[u];i!=-1;i=e[i].next)
{
int 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]);
}
int v;
if(DFN[u]==low[u])
{
cnt++;
do{
v=s[--top];
belong[v]=cnt;
instack[v]=0;
}while(u!=v);
}
}
void work()
{
REPF(i,1,n)
if(!DFN[i]) Tarjan(i);
if(cnt<=1)
{
puts("0");
return ;
}
CLEAR(in,0);
CLEAR(out,0);
for(int i=0;i<cntE;i++)
{
int u=e[i].u,v=e[i].v;
if(belong[u]!=belong[v])
in[belong[v]]++,out[belong[u]]++;
}
int d_1=0,d_2=0;
REPF(i,1,cnt)
{
if(!in[i])
d_1++;
if(!out[i])
d_2++;
}
printf("%d\n",max(d_1,d_2));
}
int main()
{
int u,v;
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
work();
}
return 0;
}

HDU 3836 Equivalent SetsTarjan+缩点)的更多相关文章

  1. hdu 3836 Equivalent Sets

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3836 Equivalent Sets Description To prove two sets A ...

  2. [tarjan] hdu 3836 Equivalent Sets

    主题链接: http://acm.hdu.edu.cn/showproblem.php? pid=3836 Equivalent Sets Time Limit: 12000/4000 MS (Jav ...

  3. hdu 3836 Equivalent Sets(tarjan+缩点)

    Problem Description To prove two sets A and B are equivalent, we can first prove A is a subset of B, ...

  4. hdu 3836 Equivalent Sets trajan缩点

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

  5. hdu - 3836 Equivalent Sets(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=3836 判断至少需要加几条边才能使图变成强连通 把图缩点之后统计入度为0的点和出度为0的点,然后两者中的最大值就是 ...

  6. hdu 3836 Equivalent Sets(强连通分量--加边)

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

  7. hdu——3836 Equivalent Sets

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

  8. HDU - 3836 Equivalent Sets (强连通分量+DAG)

    题目大意:给出N个点,M条边.要求你加入最少的边,使得这个图变成强连通分量 解题思路:先找出全部的强连通分量和桥,将强连通分量缩点.桥作为连线,就形成了DAG了 这题被坑了.用了G++交的,结果一直R ...

  9. hdoj 3836 Equivalent Sets【scc&&缩点】【求最少加多少条边使图强连通】

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

随机推荐

  1. iOS8开发~Swift(一)入门

    一.概论及Swift介绍 iOS7刚公布多时候,苹果引入了JavaScriptCore.framework用来处理JavaScript,看到了能够接触其它编程语言的契机,使iOS程序猿不用吊死在OC这 ...

  2. Android开发四大组件概述

    这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity具体解释 二.Service具体解释 三.Broadcast Receiver具体解释 四.Content Provid ...

  3. Cocos2d-x 3.1.1 lua-tests 开篇

    Cocos2d-x 3.1.1 lua-tests开篇   本篇博客打算从研究Cocos2d-x引擎提供的測试样例来写起,笔者针对Cocos2d-x 3.1.1这个版本号来介绍怎样来学习它给我们提供的 ...

  4. java中super()和this()浅析

    <span style="font-size:18px;">本质:这两个都是调用构造方法的方法.</span> 在java中,super()是在当前类的构造 ...

  5. fusionchart实现ZoomLine 源码 破解版 能够导出

    近期画油量曲线须要用到ZoomLine官网看了好几天.如今整理出来供大家參考使用 zoomline.html源码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD ...

  6. python语言学习2——安装python

    python是跨平台的,可以,在各种操作系统上安装 window平台下安装python,安装步骤: 下载安装包 下载地址:https://www.python.org/ftp/python/3.5.0 ...

  7. QT4和QT3的区别

    著名的QT库前一阵子升级到4.xx版本了,我目前在开发的一个基于QT3的软件,由于受到QThread的各种困扰,因此打算尝试将代码升级到QT4, 但是当我实际开始升级工作后,才发现QT3和QT4的变化 ...

  8. SSDTHook实例--编写稳定的Hook过滤函数

    解说怎样写Hook过滤函数,比方NewZwOpenProcess.打开进程. 非常多游戏保护都会对这个函数进行Hook. 因为我们没有游戏保护的代码,无法得知游戏公司是怎样编写这个过滤函数. 我看到非 ...

  9. Android中怎样在应用A中启动或安装应用B

    看到别人做的游戏攻略,想着自己的游戏攻略也加入新的功能,即Android中怎样在应用A中启动或安装应用B.就查了一些资料整理下来. 启动或安装对应的应用的方法: Step1:推断是否安装目标应用.仅仅 ...

  10. 利用try-catch判断变量是已声明未声明还是未赋值

    原文 利用try-catch判断变量是已声明未声明还是未赋值 这篇文章主要介绍了利用try-catch判断变量是已声明未赋值还是未声明,需要的朋友可以参考下 目的是如果一个变量是已声明未赋值,就可以直 ...