http://acm.hdu.edu.cn/showproblem.php?pid=2767

求至少添加多少条边才能变成强连通分量.统计入度为0的点和出度为0的点,取最大值即可.

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout); using namespace std;
#define N 20100
//N为最大点数
#define M 50100
//M为最大边数
int n, m;//n m 为点数和边数 struct Edge{
int from, to, nex;
bool sign;//是否为桥
}edge[M<<];
int head[N], edgenum;
void add(int u, int v){//边的起点和终点
Edge E={u, v, head[u], false};
edge[edgenum] = E;
head[u] = edgenum++;
} int DFN[N], Low[N], Stack[N], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳)
int taj;//连通分支标号,从1开始
int Belong[N];//Belong[i] 表示i点属于的连通分支
bool Instack[N];
vector<int> bcc[N]; //标号从1开始 void tarjan(int u ,int fa){
DFN[u] = Low[u] = ++ Time ;
Stack[top ++ ] = u ;
Instack[u] = ; for (int i = head[u] ; ~i ; i = edge[i].nex ){
int v = edge[i].to ;
if(DFN[v] == -)
{
tarjan(v , u) ;
Low[u] = min(Low[u] ,Low[v]) ;
if(DFN[u] < Low[v])
{
edge[i].sign = ;//为割桥
}
}
else if(Instack[v]) Low[u] = min(Low[u] ,DFN[v]) ;
}
if(Low[u] == DFN[u]){
int now;
taj ++ ; bcc[taj].clear();
do{
now = Stack[-- top] ;
Instack[now] = ;
Belong [now] = taj ;
bcc[taj].push_back(now);
}while(now != u) ;
}
} void tarjan_init(int all){
memset(DFN, -, sizeof(DFN));
memset(Instack, , sizeof(Instack));
top = Time = taj = ;
for(int i=;i<=all;i++)if(DFN[i]==- )tarjan(i, i); //注意开始点标!!!
}
vector<int>G[N];
int du[N];
void suodian(){
memset(du, , sizeof(du));
for(int i = ; i <= taj; i++)G[i].clear();
for(int i = ; i < edgenum; i++){
int u = Belong[edge[i].from], v = Belong[edge[i].to];
if(u!=v)
{
G[u].push_back(v), du[v]++;
// printf("%d %d\n",u,v);
}
}
}
void init(){memset(head, -, sizeof(head)); edgenum=;}
int main()
{
//Read();
int t,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
}
tarjan_init(n);
suodian();
int x=,y=;
for(int i=;i<=taj;i++)
{
if(du[i]==) x++; //出度为0点的个数
if(G[i].size()==) y++;
}
//printf("%d\n",j);
if(taj==) printf("0\n");
else
printf("%d\n",max(x,y));
}
return ;
}

hdu - 2667 Proving Equivalences(强连通)的更多相关文章

  1. hdu 2767 Proving Equivalences 强连通缩点

    给出n个命题,m个推导,问最少添加多少条推导,能够使全部命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每一个点都至少要有一条出去的边和一条进 ...

  2. HDU 2767:Proving Equivalences(强连通)

    题意: 一个有向图,问最少加几条边,能让它强连通 方法: 1:tarjan 缩点 2:采用如下构造法: 缩点后的图找到所有头结点和尾结点,那么,可以这么构造:把所有的尾结点连一条边到头结点,就必然可以 ...

  3. HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)

    Consider the following exercise, found in a generic linear algebra textbook. Let A be an n × n matri ...

  4. hdu 2767 Proving Equivalences

    Proving Equivalences 题意:输入一个有向图(强连通图就是定义在有向图上的),有n(1 ≤ n ≤ 20000)个节点和m(0 ≤ m ≤ 50000)条有向边:问添加几条边可使图变 ...

  5. HDU 2767 Proving Equivalences(至少增加多少条边使得有向图变成强连通图)

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  6. HDU 2767 Proving Equivalences (Tarjan)

    Proving Equivalences Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other ...

  7. HDU 2767 Proving Equivalences (强联通)

    pid=2767">http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 40 ...

  8. hdu 2767 Proving Equivalences(tarjan缩点)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2767 题意:问最少加多少边可以让所有点都相互连通. 题解:如果强连通分量就1个直接输出0,否者输出入度 ...

  9. UVALive Proving Equivalences (强连通分量,常规)

    题意: 给一个有向图,问添加几条边可以使其强连通. 思路: tarjan算法求强连通分量,然后缩点求各个强连通分量的出入度,答案是max(入度为0的缩点个数,出度为0的缩点个数). #include ...

随机推荐

  1. Codeforces Round #272 (Div. 2)-C. Dreamoon and Sums

    http://codeforces.com/contest/476/problem/C C. Dreamoon and Sums time limit per test 1.5 seconds mem ...

  2. Jarvis OJ-level3

    使用ret2libc攻击方法绕过数据执行保护 from pwn import* conn = remote("pwn2.jarvisoj.com",9879) elf = ELF( ...

  3. POI 读取 Excel 文件

    import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.Out ...

  4. commons-logging 和log4j包下载 Spring根据XML配置文件生成对象

    需要用到Spring压缩包中的四个核心JAR包 beans .context.core 和expression 下载地址: https://pan.baidu.com/s/1qXLHzAW 以及日志j ...

  5. Linux用户身份(命令详解与补正)

    基于Red Hat Enterprise Linux 7.5 Linux中的root就是存在于所有类UNIX系统中的超级用户,持有最高管理权限,能添加/删除用户.开关机.关闭或开启硬件或者系统服务等, ...

  6. The eleven Day

    库操作 一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等 performance_schema ...

  7. jmeter压力测试入门

    http://www.51testing.com/html/80/n-853680.html http://blog.csdn.net/vincy_zhao/article/details/70238 ...

  8. Programming Python 3rd Edition 第三版 pdf chm下载

    Programming Python 作为一款经典系列书籍 非常的耐看 建议有志于学习python的童鞋好好看看 网上 Programming Python第四版的 pdf 下载非常容易 也就是最新的 ...

  9. Python中你不知道的特性

    内置函数print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) 本函数是实现对象以字符串表示的方式格式化输出到流文件对象fil ...

  10. OSPF 一 基础

    本节介绍ospf路由选择协议    为链路状态  路由选择协议 一  分类 open shortest path first   开放最短路优先   公有协议 单区域的ospf实施  运行在一个自治系 ...