hdu4635 Strongly connected(tarjan计算强连通通分量+缩点+思想)

Strongly connected

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2714    Accepted Submission(s): 1128


Problem Description
Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the graph is still a simple directed graph. Also, after you add these edges, this graph must NOT be strongly connected.
A simple directed graph is a directed graph having no multiple edges or graph loops.
A strongly connected digraph is a directed graph in which it is possible to reach any node starting from any other node by traversing edges in the direction(s) in which they point. 
 

Input
The first line of date is an integer T, which is the number of the text cases.
Then T cases follow, each case starts of two numbers N and M, 1<=N<=100000, 1<=M<=100000, representing the number of nodes and the number of edges, then M lines follow. Each line contains two integers x and y, means that there is a edge from x to y.
 

Output
For each case, you should output the maximum number of the edges you can add.
If the original graph is strongly connected, just output -1.
 

Sample Input
 
   
3 3 3 1 2 2 3 3 1 3 3 1 2 2 3 1 3 6 6 1 2 2 3 3 1 4 5 5 6 6 4
 

Sample Output
 
   
Case 1: -1 Case 2: 1 Case 3: 15
 

Source
2013 Multi-University Training Contest 4
 

Recommend
zhuyuanchen520   |   We have carefully selected several similar problems for you:   6022  6021  6020  6019  6018 
 

Statistic |  Submit |  Discuss |  Note

题意大概就是:给你一个DAG图,问最多添加多少条边后此DAG图依然是不是强连通图。

对于这道题而言。我们可以反着思考。如果此图是个强连通图,那么最多能有多少条边。

假设最后所求的DAG图有两个部分X图和Y图.此时X图和Y图肯定各是个强连通图,并且X图和Y图之间只有单向的边。

这样才能使DAG图边数最多

假设X图的顶点数为x,Y图的顶点数为y,则DAG图的顶点数为x+y=n

则有:

  • 如果使X图强连通,边数最多为x*(x-1)(即X图的每个顶点到X图其它每个顶点都有一条单向边)
  • 如果使Y图强连通,边数最多为y*(y-1)
  • X图和Y图之间只有单项的边,则边数最多为x*y(即X图的每个顶点到Y图每个顶点都有一条单向边)
通过以上可以求得边数F(DAG)=x*y+x*(x-1)+y*(y-1)=n*n-n-x*y.即DAG图的边数最多为n*n-n-x*y.
由于n一定,所以本题就可以转化为求x*y的最小值,又因为x+y=n。所以x和y差值越大结果越小。
进而本题转化为查找DAG图中顶点最小的强连通分量。
F(DAG)减去已有的边数m即是所求结果。

计算强连通分量可以使用tarjan算法,在统计过程中对强连通分量进行缩点即可~由于我们要求X图和Y图之间只有单向的边,所以
我们要找的Y图 一定是入度为0或者出度为0的强连通分量,否则 此DAG图为强连通图 。

代码如下:
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define N 100000+10
vectorlink[N];
bool inStack[N];
int dfn[N];
int low[N];
int fa[N];//通过DAG图中 某个顶点所属的强连通分量序号 
int point[N];//统计缩点后某强连通分量的顶点数 
int in[N];//缩点后某强连通分量的入度 
int out[N];//缩点后某强连通分量的出度 
int time;//时间戳 
int sum;//DAG图中连通分量的个数 
int n,m;
stacks;
void doTarjan(int x)
{
	dfn[x]=low[x]=++time;
	s.push(x);
	inStack[x]=true;
	for(int i=0;i





你可能感兴趣的:(【搜索】,【强连通图】,Acm竞赛)