题意:

  给一些集合 要求证明所有集合是相同的

  证明方法是,如果$A∈B$,$B∈A$那么$A=B$成立

  每一次证明可以得出一个$X∈Y$

  现在已经证明一些$A∈B$成立

  求,最少再证明多少次,就可以完成要求

分析

  其实就等价于给一个有向图,问你再加入多少个边可以使得图变为强连通图

  给一个图论经典结论:

  "对于一个有向无环图(DAG),若想让它成为强连通图,至少需要添加$max(a,b)$条边 $a$为入度为0的点的数量,$b$为出度为0的点的数量"

  而对于一个有向图,其每个强连通分量都互相可达,也就是只要到达任意一个点,即可到达内部所有的点

  现在,只要对于强连通分量进行缩点,再新图中统计出入度数即可得到答案

  *注意,如果强连通分量只有1个,答案应该是0而不是1

#include <bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define per(ii,a,b) for(int ii=a;ii>=b;ii--)
#define show(x) cout<<#x<<"="<<x<<endl
#define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
#define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
#define showa(a,b) cout<<#a<<'['<<#b<<"]="<<a[b]<<endl
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
int stk[maxn],top,cnt,dfn[maxn],low[maxn],numc,belong[maxn],vis[maxn];
struct node {int to,cost,next;}e[maxm];int head[maxn],nume;
void add(int a,int b,int c=1){e[++nume]=(node){b,c,head[a]};head[a]=nume;}
void tdfs(int now){
dfn[now]=low[now]=++cnt;
stk[top++]=now;
vis[now]=1;
for(int i=head[now];i;i=e[i].next){
int to=e[i].to;
if(!dfn[to]){tdfs(to);low[now]=min(low[now],low[to]);}
else if(vis[to]) low[now]=min(low[now],dfn[to]);
}
if(low[now]==dfn[now]){
numc++;
int to;
do{
to=stk[--top];
belong[to]=numc;
vis[to]=0;
}while(to!=now);
}
}
void tarjan(int numv=n){
for(int i=1;i<=numv;i++){
if(!dfn[i]) tdfs(i);
}
}
void ginit(){
nume=top=numc=cnt=0;
memset(head,0,sizeof head);
memset(dfn,0,sizeof dfn);
}
int din[maxn],dout[maxn]; int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif while(cin>>n>>m){
if(m==0) {
cout<<n<<endl;
continue;
}
ginit();
memset(din,0,sizeof din);
memset(dout,0,sizeof dout);
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
add(a,b);
}
tarjan();
for(int i=1;i<=n;i++){
for(int j=head[i];j;j=e[j].next){
if(belong[i]==belong[e[j].to])continue;
dout[belong[i]]++;
din[belong[e[j].to]]++;
}
}
int a=0,b=0;
for(int i=1;i<=numc;i++){
if(din[i]==0)a++;
if(dout[i]==0)b++;
}
if(numc==1) a=b=0;
cout<<max(a,b)<<endl;
} #ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

  

Equivalent Sets HDU - 3836 2011多校I tarjan强连通分量的更多相关文章

  1. Equivalent Sets HDU - 3836 (Tarjan)

    题目说给出一些子集,如果A是B的子集,B是A的子集,那么A和B就是相等的,然后给出n个集合m个关系,m个关系表示u是v的子集,问你最小再添加多少个关系可以让这n个集合都是相等的 如果这n个几个都是互相 ...

  2. HDU 1269 迷宫城堡(判断有向图强连通分量的个数,tarjan算法)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. HDU 4685 Prince and Princess(二分图+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

  4. HDU 3861 The King’s Problem(强连通分量+最小路径覆盖)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意: 在csdn王国里面, 国王有一个新的问题. 这里有N个城市M条单行路,为了让他的王国 ...

  5. HDU 3861 The King's Problem(强连通分量缩点+最小路径覆盖)

    http://acm.hdu.edu.cn/showproblem.php?pid=3861 题意: 国王要对n个城市进行规划,将这些城市分成若干个城市,强连通的城市必须处于一个州,另外一个州内的任意 ...

  6. 【BZOJ2438】 [中山市选2011]杀人游戏 tarjan强连通分量+缩点

    Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是 ...

  7. 【(最小权点基)tarjan强连通分量缩点+tarjan模板】HDU 5934 Bomb

    [AC] #include<bits/stdc++.h> using namespace std; typedef long long ll; int n; ; ; const int i ...

  8. HDU - 1269 迷宫城堡(有向图的强连通分量)

    d.看一个图是不是强连通图 s.求出强连通分量,看看有没有一个强连通分量包含所有点. c.Tarjan /* Tarjan算法 复杂度O(N+M) */ #include<iostream> ...

  9. [tarjan] hdu 3836 Equivalent Sets

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

随机推荐

  1. python -- conda pytorch

    Linux上用anaconda安装pytorch Pytorch是一个非常优雅的深度学习框架.使用anaconda可以非常方便地安装pytorch.下面我介绍一下用anaconda安装pytorch的 ...

  2. <HTML深入浅出> 读书笔记

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  3. UDF简记

    摘要: 1.开发UDF 2.开发UDAF 3.开发UDTF 4.部署与测试 5.一个简单的实例 内容:1.开发UDF 函数类需要继承org.apache.hadoop.hive.ql.UDF 实现ev ...

  4. ArcGis Python脚本——要素图斑自动编号,自上而下,从左到右

    原理: 利用图斑最小外包矩形的左上角坐标(数学坐标)Y坐标将序.X坐标升序的方式获取自上而下,从左到右的要素记录排序,然后遍历编号. "!shape.extent.xmin!"计算 ...

  5. tedu训练营day01

    1.三大操作系统 1.Unix :MacOS 2.Linux :Ubuntu18.04 .CentOS.RedHat 3.Windows :Win7.Win8.Win102.VMware Workst ...

  6. 混合app开发--js和webview之间的交互总结

    使用场景:原生APP内嵌套H5页面,app使用的是webview框架进行嵌套 这样就存在两种情况 1.原生app调用H5的方法 2.H5调用app的方法 分别讲解下,其实app与H5之间的交互式非常简 ...

  7. git 提交解决冲突(转载)

    转载 git 提交解决冲突 http://www.cnblogs.com/qinbb/p/5972308.html   一:git命令在提交代码前,没有pull拉最新的代码,因此再次提交出现了冲突. ...

  8. java伪代码 大道至简第一章

    import.java.大道至简.*; //一·编程的精义 import.java.编程的精义.*; public class BIANCHENGDEJINGYI { if(愚公死了) 愚公的儿子,孙 ...

  9. 使用C++ stringstream来进行数据类型转换

    参考链接: http://blog.csdn.net/tao_627/article/details/39000779

  10. eclipse中一些常见svn图标的含义

    项目视图   The Package Explorer view - 已忽略版本控制的文件.可以通过Window → Preferences → Team → Ignored Resources.来忽 ...