On the mysterious continent of Tamriel, there is a great empire founded by human. To develope the trade, the East Empire Company is set up to transport goods from place to place. Recently, the company wants to start their business in Solstheim, which is consists of N islands. Luckily, there are already M sea routes. All routes are one-way, and the i-th route can transport person and goods from island u to v . Now, the company nominates you a particular job to plan some new routes to make sure that person and goods can be transported between any two islands. Furthermore, because the neighboring regions are under attack by an increasing number of dragons, limited resources can be used to set up new routes. So you should plan to build new routes as few as possible. Input Format The first line contains an integer T, indicating that there are T test cases. For each test case, the first line includes two integers N (N ≤ 10000) and M (M ≤ 100000), as described above. After that there are M lines. Each line contains two integers u and v . Output Format For each test case output one integer, represent the least number of routes required to new.

Sample Input

2

4 3

1 2

2 3

3 4

4 4

1 2

1 4

3 2

3 4

Sample Output

1

2
题意: 加最少的边,使有向图是一个强联通图;
思路: Tarjan算法求出强联通分量之后缩点成一个DAG图,a是DAG图入度为0的点数,b是DAG图出度为0的点数,
因为要为所有入度为0的点加入边,为所有出度为0的点加出边,所以至少要加的边数就是max(a, b);
要注意的是,当整个图原本就是强联通图时(即只有一个强联通分量时),不需要加边;

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack> using namespace std;
const int N = + ; vector<int> edge[N];
stack<int> S; int in[N], out[N], scc[N]; class Trajan{
private:
int dfn[N], low[N];
public:
int dfs_clock, scc_cnt;
void DFS(int u){
dfn[u] = low[u] = ++ dfs_clock;
S.push( u );
for(int i = edge[u].size() - ; i >= ; -- i){
int v = edge[u][i];
if(!dfn[v]){
DFS( v );
if(low[v] < low[u]) low[u] = low[v]; }else if(!scc[v] && dfn[v] < low[u])
low[u] = dfn[v];
}
if(low[u] == dfn[u]){
++ scc_cnt;
while(true){
int v = S.top(); S.pop();
scc[v] = scc_cnt;
if(v == u) break;
}
}
} void Work_scc(int n){
dfs_clock = scc_cnt = ;
for(int i = ; i < N; ++ i)
dfn[i] = low[i] = scc[i] = ; for(int i = ; i <= n; ++ i)
if(!dfn[i]) DFS( i ); }
}Tar; void Solve_question(int n){
for(int i = ; i <= Tar.scc_cnt; ++ i)
in[i] = out[i] = ; for(int i = ; i <= n; i++)
for(int j = edge[i].size() - ; j >= ; -- j)
if(scc[i] != scc[edge[i][j]])
++ out[scc[i]], ++ in[scc[edge[i][j]]]; int in_cnt = , out_cnt = ;
for(int i = ; i <= Tar.scc_cnt; ++i){
if(!in[i]) ++ in_cnt;
if(!out[i]) ++out_cnt;
}
printf("%d\n", Tar.scc_cnt > ? max(in_cnt, out_cnt) : ); //只有一个点时无需加边
} void Input_data(int &n, int &m){
scanf("%d %d", &n, &m);
for(int i = ; i <= n; i++) edge[i].clear();
int u, v;
while(m --){
scanf("%d %d", &u, &v);
edge[u].push_back(v);
}
} int main(){
int T, n, m;
scanf("%d", &T);
while(T --){
Input_data(n, m);
Tar.Work_scc( n );
Solve_question( n );
}
}

2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛 F. Islands的更多相关文章

  1. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  2. Skiing 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛H题(拓扑序求有向图最长路)

    参考博客(感谢博主):http://blog.csdn.net/yo_bc/article/details/77917288 题意: 给定一个有向无环图,求该图的最长路. 思路: 由于是有向无环图,所 ...

  3. 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 M. Frequent Subsets Problem【状态压缩】

    2017 ACM-ICPC 亚洲区(南宁赛区)网络赛  M. Frequent Subsets Problem 题意:给定N和α还有M个U={1,2,3,...N}的子集,求子集X个数,X满足:X是U ...

  4. 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)

    摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5 ...

  5. ICPC 2018 徐州赛区网络赛

    ACM-ICPC 2018 徐州赛区网络赛  去年博客记录过这场比赛经历:该死的水题  一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进.     D. Easy Math 题意:   ...

  6. 【2017 ACM/ICPC 乌鲁木齐赛区网络赛环境测试赛 E】蒜头君的排序

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] 莫队算法+树状数组. 区间增加1或减少1. 对逆序对的影响是固定的. (用冒泡排序变成升序的交换次数,就是逆序对的个数) [错的次数] 0 [ ...

  7. 2017 乌鲁木齐赛区网络赛 J Our Journey of Dalian Ends 费用流

    题目描述: Life is a journey, and the road we travel has twists and turns, which sometimes lead us to une ...

  8. [刷题]ACM/ICPC 2016北京赛站网络赛 第1题 第3题

    第一次玩ACM...有点小紧张小兴奋.这题目好难啊,只是网赛就这么难...只把最简单的两题做出来了. 题目1: 代码: //#define _ACM_ #include<iostream> ...

  9. 2016 ACM/ICPC亚洲区大连站-重现赛 解题报告

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5979 按AC顺序: I - Convex Time limit    1000 ms Memory li ...

随机推荐

  1. 洛谷P1576 最小花费x

    题目背景 题目描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A最少需要多少钱使得转账后B收到100元 ...

  2. NS3安装

    1.添加源sudo vim /etc/apt/sources.list deb http://archive.ubuntu.com/ubuntu/ trusty main universe restr ...

  3. Moco 详解

    一.下载及安装: 运行环境: JAVA环境 linux 下载地址:https://github.com/dreamhead/moco 下载下来的是一个jar包,如:moco-runner-0.12.0 ...

  4. 微信小程序_(组件)组件基础

    (progress.text.block) 组件基础效果 官方文档:传送门 Page({ /** * 页面的初始数据 */ data: { text:"Gary 微信小程序\n", ...

  5. jquery 动态增加table行,动态删除table行

    在html中我们大量的用到了局部刷新,局部刷新就是使用js来动态的修改html局部的数据.下面来介绍下使用jquery来动态的增加table的行,当然这种方式可以适用到任何的html组件中去. < ...

  6. C++入门经典-例3.7-用条件运算符判断数的奇偶性

    1:条件运算符是一个三目运算符,能像判断语句一样完成判断.例如: max=(iA>iB) ? iA:iB; 意思是先判断iA是否大于iB,如果是,则max取iA的值,如果不是则取iB的值. 如果 ...

  7. MVC 小demo

    .field-validation-error { color: #f00; } .field-validation-valid { display: none; } .input-validatio ...

  8. SpringBoot上传文件临时失效问题

    线上的系统中不能上传文件了,出现如下错误: org.springframework.web.multipart.MultipartException: Could not parse multipar ...

  9. 选择company回显appname

    function showSupCompany() { var obj = {}; obj.label = ScompanyId.getSelectedLabel(); obj.value = Sco ...

  10. 解决ssh链接慢问题

    1,ssh -v root@ip 2,查看哪里卡住了 一般情况就是卡在debug1: SSH2_MSG_SERVICE_ACCEPT received 3,如果是上面卡住了 修改/etc/ssh/ss ...