HDU 4635 Strongly connected (有向图的强连通分量)

Strongly connected

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

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

题解

问:最多加多少条边,使得原图不是强连通图

可以反向思考,假设原图已满边,即sum=n*(n-1),减去多少条边使其不是强连通图

直接加边sss=n*(n-1)-m;

用Tarjan求出强连通分量并缩点,将缩好的点分为两部分,一部分到另一部分没有边(即这个点的入度或出度为0),然后用sss减去这两部分能构成的变数。

假设第i个强连通分量有num[i]个点,则它与另一半的图所能连接的边数为num[i]*(n-num[i]),求这个的最小值,减去就行了。

代码

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

const int MAXN = 100000+100;
/*
 * Tarjan算法
 * 复杂度O(N+M)
 */
struct Edge{
    int to,next;
}edge[MAXN];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
int Index,top;
int scc;//强连通分量的个数
bool Instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc

void init()
{
    tot=0;
    memset(head,-1,sizeof(head));
}

void addedge(int u,int v)
{
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}

void Tarjan(int u)
{
    int v;
    Low[u]=DFN[u]=++Index;
    Stack[top++]=u;
    Instack[u]=true;
    for(int i=head[u];i!=-1;i=edge[i].next){
        v=edge[i].to;
        if(!DFN[v]){
            Tarjan(v);
            if(Low[u]>Low[v]) Low[u]=Low[v];
        }
        else if(Instack[v]&&Low[u]>DFN[v])
            Low[u]=DFN[v];
    }
    if(Low[u]==DFN[u]){
        scc++;
        do{
            v=Stack[--top];
            Instack[v]=false;
            Belong[v]=scc;
            num[scc]++;
        }
        while(v!=u);
    }
}

void solve(int n)
{
    memset(DFN,0,sizeof(DFN));
    memset(Instack,false,sizeof(Instack));
    memset(num,0,sizeof(num));
    Index=top=scc=0;
    for(int i=1;i<=n;i++)
        if(!DFN[i])
           Tarjan(i);
}

int in[MAXN],out[MAXN];

int main()
{
    int T;
    int iCase=0;
    scanf("%d",&T);
    while(T--){
        iCase++;
        init();
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        solve(n);
        if(scc==1){
            printf("Case %d: -1\n",iCase);
            continue;
        }
        for(int i=1;i<=scc;i++){
            in[i]=0;
            out[i]=0;
        }
        for(int u=1;u<=n;u++){
            for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(Belong[u]==Belong[v]) continue;
                out[Belong[u]]++;
                in[Belong[v]]++;
            }
        }
        long long sss=(long long)n*(n-1)-m;
        long long ans=0;
        for(int i=1;i<=scc;i++){
            if(in[i]==0||out[i]==0)
                ans=max(ans,sss-(long long)num[i]*(n-num[i]));
        }
        printf("Case %d: %lld\n",iCase,ans);
    }
}
时间: 2024-07-28 16:06:57

HDU 4635 Strongly connected (有向图的强连通分量)的相关文章

[tarjan] hdu 4635 Strongly connected

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1568    Accepted Submission(s): 654 Problem Description Give a simple dir

HDU 4635 Strongly connected(强连通分量,变形)

题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提下,要添加尽可能多的边.边至多有n*(n-1)条,而已经给了m条,那么所能添加的边数不可能超过k=n*(n-1)-m. 这k条边还有部分不能添加,一添加立刻就强连通.一个强连通图最少只需要n条边,根据强连通的特性,缩点之后必定是不会有环的存在的,那么只要继续保持没有环的存在即可.我们只要让其中1个强

HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】

Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4635 Description Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can

HDU 4635 Strongly connected(强连通)经典

Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1828    Accepted Submission(s): 752 Problem Description Give a simple directed graph with N nodes and M edges. Please tell me

hdu 4635 Strongly connected (tarjan)

题意:给一个n个顶点m条弧的简单有向图(无环无重边),求最多能够加入多少条弧使得加入后的有向图仍为简单有向图且不是一个强连通图.假设给的简单有向图本来就是强连通图,那么输出-1. 分析: 1.用tarjan算法求出强连通分量的个数,假设个数为1,那么输出-1,结束,否则运行2 2.如果将一些强连通分量合并为有n1个顶点简单全然图1,而将剩下的强连通分量合并为n2个顶点的简单全然图2,跨这两个简单全然图的弧的方向仅仅能是单向的,如果m1为全然图1内部的弧的数量,m2为为全然图2内部的弧的数量.m3

HDU 4635 Strongly connected(强连通分量缩点+数学思想)

题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢……有人给出这样的答案,找到分量中点数最少的块,把它的所有入边都去掉……好像是对的,但是万一这个块本来就有一个入度怎么办?这个边是不可以删的啊.所以我觉得这种办法是有点的问题的,所以最靠谱的方法还是斌哥他们给出的方法,最后的时候把点分成两个集合x和y,x和y本身都是完全图块,然后让x中的每一个点都指向y

HDU 4635 Strongly connected 强连通分量

参考:http://www.cnblogs.com/jackge/p/3231767.html 讲的很好 感悟:最好的情况肯定是完全图,但是不允许,所以一定是有些符合u->v,但是v不能到u, 在保证这样的情况,最大化边数,最终会形成两个图,然后应用不等式 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath>

Hdu 4635 Strongly connected

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4635 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 100005; 9 const int INF

图-&gt;连通性-&gt;有向图的强连通分量

文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). 用深度优先搜索求有向图的强连通分量的方法如下并假设有向图的存储结构为十字链表. 1 在有向图G上,从某个定点出发沿以该顶点为尾的弧