题意:

给你一张有向图,问你最少加多少条边这张图强连通

思路:

缩点之后,如果不为1个点,答案为出度为0与入度为0的点的数量的最大值

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
//#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional>
#include<unordered_map> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 5e4+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); vector<int>g[maxn];
int f[maxn];
int color[maxn],dfn[maxn],low[maxn],stack[maxn],vis[maxn],cnt[maxn];
int in[maxn],out[maxn];
int top,n,m,sum,ans;
int deep = ;
void tarjan(int u){
dfn[u]=++deep;
low[u]=deep;
vis[u]=;
stack[++top]=u;
int sz=g[u].size();
for(int i=;i<sz;i++){
int v=g[u][i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else{
if(vis[v]){
low[u]=min(low[u],low[v]);
}
}
}
if(dfn[u]==low[u]){
color[u]=++sum;
vis[u]=;
while(stack[top]!=u){
color[stack[top]]=sum;
vis[stack[top--]]=;
}
top--;
}
return;
}
PI edge[maxn];
vector<int>v[maxn];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
void dfs(int x, int fa){
if(x!=fa){
int t1 = find(x);
int t2 = find(fa);
f[t1]=t2;
}
if(v[x].size()==&&x!=fa&&vis[x]==){vis[x]=;ans++;}
for(int i = ; i <(int)v[x].size(); i++){
int y = v[x][i];
dfs(y,fa);
}
}
int main() {
while(~scanf("%d %d", &n, &m)){
deep=;
top=ans=sum=;
for(int i = ; i <= n; i++){
f[i]=i;
color[i]=low[i]=dfn[i]=stack[i]=vis[i]=cnt[i]=;
g[i].clear();
v[i].clear();in[i]=out[i]=;
}
for(int i = ; i <= m; i++){
int x,y;
scanf("%d %d", &x, &y);
edge[i] = make_pair(x,y);
g[x].pb(y);
}
for(int i = ; i <= n; i++){
if(!dfn[i])tarjan(i);
}
/*for(int i = 1; i <= n; i++){
printf("--%d %d %d\n",i,color[i],low[i]);
}*/
//suo dian
for(int i = ; i <= n; i++)vis[i]=;
for(int i = ; i <= m; i++){
int x = edge[i].fst;
int y = edge[i].sc;
x = color[x];
y = color[y];
if(x!=y){
v[x].pb(y);
in[y]++;
out[x]++;
}
}
int In=;
int Ou=;
for(int i = ; i <= sum; i++){
if(in[i]==)In++;
if(out[i]==)Ou++;
}
int ans = max(In,Ou);
if(ans==)ans--;
printf("%d\n",ans); }
return ;
}
/*
4 3
1 2
2 3
4 3 4 3
1 2
2 3
3 4 8 6
1 2
1 3
1 5
3 4
3 6
6 7 6 5
1 2
2 3
3 1
3 5
1 4 2 2
1 2
2 1 3 3
1 2
2 3
1 3 7 6
1 2
2 3
1 3
4 5
4 6
4 7 4 5
1 2
1 3
1 4
2 3
3 4 4 5
1 2
1 3
1 4
2 3
4 3 3 1
1 2
*/

HDU3836 Equivalent Sets (Tarjan缩点+贪心)的更多相关文章

  1. hdu 3836 Equivalent Sets trajan缩点

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

  2. 20190716NOIP模拟赛T2 通讯(tarjan缩点+贪心)

    题目描述 “这一切都是命运石之门的选择.” 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短 信,并由此得知了伦太郎制作出了电话微波炉(仮). 为了掌握时间机器的技术,SERN总部 ...

  3. 【洛谷P5008 逛庭院】tarjan缩点+贪心

    既然没有题解,那么我就来提供给一份. -- 首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪 ...

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

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

  5. [tarjan] hdu 3836 Equivalent Sets

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

  6. hdu 3836 Equivalent Sets

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

  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

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

  9. 【HDOJ2767】【Tarjan缩点】

    http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 4000/2000 MS (Java/O ...

随机推荐

  1. Go 开发关键技术指南 | 敢问路在何方?(内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 Go 开发关键技术指南文章目录: 为什么你要选择 Go? Go 面向失败编程 带着服务器编程金刚经走进 2020 年 敢问路在何方? Go 开发指南大图 ...

  2. 【转】Java 正则表达式详解

    正则表达式30分钟入门教程 常用正则表达式 如果你曾经用过Perl或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单. 如果你不熟悉这个术语,那么“正则表达式”(R ...

  3. python报错:not supported between instances of 'str' and 'int'

    not supported between instances of 'str' and 'int' : 意思就是字符串不能和int类型的数值比较

  4. js中如何将伪数组转换成数组

    伪数组:不能调用数组的方法, 1.对象是按索引方式存储数据的 2.它具备length属性 {0:'a',1:'b',length:2} //es5伪数组转换成数组 let args = [].slic ...

  5. gcd竞赛模板

    int gcd(int a,int b) { ) return a; return gcd(b,a%b); }

  6. codeforces 上的找两人的幸运天

    Bob and Alice are often participating in various programming competitions. Like many competitive pro ...

  7. bzoj 2683 CDQ分治

    题目描述 你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作: 命令 参数限制 内容 1 x y A 1<=x,y<=N,A是正整数 将格子x,y里的数 ...

  8. C++ 引用分析

    引用 左值引用,建立既存对象的别名 右值引用,可用于为临时对象延长生命周期 转发引用,保持函数实参的类别 悬置引用,对象生命周期已经结束的引用,访问改引用为未定义行为 值类别,左值,纯右值,亡值 st ...

  9. NOI2.4 2011

    描述 已知长度最大为200位的正整数n,请求出2011^n的后四位. 输入 第一行为一个正整数k,代表有k组数据,k<=200接下来的k行, 每行都有一个正整数n,n的位数<=200 输出 ...

  10. Linux 常用工具sysstat之iostat

    命令解释 用于输出CPU和磁盘I/O相关的统计信息:iostat依赖于sysstat软件包 命令格式 iostat [ 选项 ] [<时间间隔> [<次数>]] 常用选项 -c ...