传送门

很开心,wrong了十多发。因为不认真写错了一个字母,找了一个晚上的bug。

题意:给你一个单向图,问你加多少边能够变成一个强连通图,很显然首先是通过tanjar缩点将该图转化为了DAG,看了博客发现了一个很重要的性质,对于某个DAG加多少条边能成为强连通。

边数=max(入度为0的点个数,初度为0的点个数)

为啥呢?首先我们假设可以自己想象一哈,每一个DAG图可以看作树的元素。设入度为0的点(即树的根)个数为a,对于每一个出度为0的点(即树的以叶子节点)个数为b。如果要成为强连通图,我们必须从叶子节点引出一条边,也必须对一个根引入一条边。

哦吼,那么不是说我从出度为0的点引出一条边到入度为0的点,那么这些就构成了环。所以剩下的abs(a-b)的入度为0,出度为0的点随便连接一条边到树里的任意元素就可以喽,所以边数=min(a,b)+abs(a-b)=max(a,b);这就是上边大字的验证。

所以呢,可以不用建新的图,但是当本身就是强连通图时,cnt==1,就不需要边了,特判一哈。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define me(a,b) memset(a,b,sizeof(a))
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
typedef long long ll;
using namespace std;
const int maxn=2e4+4;
const int maxnn=5e4+4;
int cnt,top,t,sign,n,m;
int head[maxn],low[maxn],dfn[maxn],Stack[maxn],inStack[maxn];
int in[maxn],out[maxn],belong[maxn];
struct node
{int to,p;
}edge[maxnn];
void add(int u,int v)
{edge[sign]=node{v,head[u]};head[u]=sign++;
}
void init()
{cnt=top=t=sign=0;for(int i=0;i<=n;i++){in[i]=out[i]=0;low[i]=dfn[i]=inStack[i]=0;head[i]=-1;}
}
void tanjar(int u)
{low[u]=dfn[u]=++t;Stack[++top]=u;inStack[u]=1;for(int i=head[u];i!=-1;i=edge[i].p){int v=edge[i].to;if(!dfn[v]){tanjar(v);low[u]=min(low[u],low[v]);}else if(inStack[v])low[u]=min(low[u],dfn[v]);}int x;if(low[u]==dfn[u]){cnt++;do{x=Stack[top--];inStack[x]=0;belong[x]=cnt;}while(x!=u);}
}
int main()
{int T,x,y;scanf("%d",&T);while(T--){scanf("%d %d",&n,&m);init();while(m--){scanf("%d %d",&x,&y);add(x,y);}for(int i=1;i<=n;i++){if(!dfn[i])tanjar(i);}if(cnt==1)cout<<0<<endl;else{for(int i=1;i<=n;i++){for(int j=head[i];j!=-1;j=edge[j].p){int e=edge[j].to;if(belong[i]!=belong[e]){in[belong[e]]=1;out[belong[i]]=1;}}}int a=0,b=0;for(int i=1;i<=cnt;i++){if(in[i]==0) a++;if(out[i]==0) b++;}printf("%d\n",max(a,b));}}return 0;
}

HDU - 2767 Proving Equivalences tanjar强连通-DAG性质相关推荐

  1. hdu 2767 Proving Equivalences (加多少边使其强连通)

    题意大致是有n个 推断,和m个推出关系,输入a b代表a能推出b,问要使n个推断能够互相推出,至少要证明几个推断.a推出b,在图中是由a指向b的有向边,能够相互推出,即加最少的边使图变成强连通图 思路 ...

  2. hdu - 2667 Proving Equivalences(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=2767 求至少添加多少条边才能变成强连通分量.统计入度为0的点和出度为0的点,取最大值即可. 1 #include ...

  3. 有向图 加最少的边 成为强连通分量的证明 poj 1236 hdu 2767

    poj 1236: 题目大意:给出一个有向图, 任务一: 求最少的点,使得从这些点出发可以遍历整张图  任务二: 求最少加多少边 使整个图变成一个强连通分量. 首先任务一很好做, 只要缩点 之后 求 ...

  4. UVa 12167 HDU 2767 强连通分量 Proving Equivalences

    题意:给出一个有向图,问最少添加几条有向边使得原图强连通. 解法:求出SCC后缩点,统计一下出度为0的点和入度为0的点,二者取最大值就是答案. 还有个特殊情况就是本身就是强连通的话,答案就是0. 1 ...

  5. 【强连通分量】Proving Equivalences

    [题目链接]hdu-2767 [题目描述] Consider the following exercise, found in a generic linear algebra textbook. L ...

  6. HDU 5934:Bomb(强连通缩点)

    http://acm.hdu.edu.cn/showproblem.php?pid=5934 题意:有N个炸弹,每个炸弹有一个坐标,一个爆炸范围和一个爆炸花费,如果一个炸弹的爆炸范围内有另外的炸弹,那 ...

  7. 【HDU - 5934】Bomb (强连通分量Tarjan + 缩点)

    题干: There are NN bombs needing exploding. Each bomb has three attributes: exploding radius riri, pos ...

  8. hdu 1271 小希的迷宫(树的性质,并查集)

    小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  9. hdu 1269(Tarjan求强连通分量)

    这道题目就是求强连通分量... 这里采用的是Tarjan算法:http://m.blog.csdn.net/blog/qq574857122/16361033 AC代码: #include<io ...

最新文章

  1. 新型量子计算机首个基本元件问世,扩展性更强运算速度更快
  2. XLNet再次超越BERT,技术发展太快,如何才能跟得上节奏?
  3. android 麦克风耳机,Android force AudioRecord使用耳机麦克风
  4. Spring Boot API 接口文档 Swagger 入门
  5. 快钱接口php,快钱支付接口
  6. alter table add column多个字段_ElementUI表格el-table表头固定自适应高度解决方案
  7. wireshark windows版数据过滤插件安装及使用
  8. 微信支付php案例,小程序微信支付php案例
  9. 为什么要使用MQ消息中间件?
  10. c语言 停车管理系统
  11. Android 身份证号码校验
  12. flash遮罩动画的使用技巧
  13. 比特红:万物可直播、人人能带货
  14. (python)bing搜索引擎API接入测试
  15. 基于 Ubuntu 玩转 Hudi Docker Demo (2)—— 测试数据写入 Kafka
  16. 无人驾驶计算机控制系统,自动驾驶汽车的无人驾驶系统三大模块是什么?
  17. quark h5 学习
  18. Zepto中文API
  19. linux 重试密码次数超,Linux中密码策略
  20. 输出魔方阵,所谓魔方阵是指这样的方阵,它的每一行,每一列和对角线之和均相等。例如,三阶魔方阵为

热门文章

  1. Git 的简单使用及ssh配置问题-赖大大
  2. Android初学第36天
  3. MySQL之pymysql模块
  4. Android OpenGL ES(十一)绘制一个20面体 .
  5. UIScrollView上面放一个UIScrollView或者UITableView拖动时候 View出现一闪一闪解决办法...
  6. Ubuntu 12.04安装Sun JDK 6
  7. 快速设置戴尔latitude笔记本的触摸板和指点杆
  8. LINUX下SVN命令大全
  9. 一生受益的三个小故事
  10. 动态更新 AGS Cache