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 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

题意:给一个n个点的简单有向图,问最多能加多少条边使得该图仍然是简单有向图,且不是强连通图。简单有向图定义:没有重边。无自环。 强连通图:整个图缩点后就仅仅有一个点。里面包括n个原点,也就是一个连通分量。

假设一開始就是一个强连通图。则输出-1。

解题:要加边最多那么加边后的图连通分量越少越好,那么连通分量最少也就是2个。先用n个点构造一个全然图(有向图有:n*(n-1)条边,无向图有:n*(n-1)/2条边)。再用构造的边 减去原来有的m条边=ans。再用强连通算法缩点。记录每一个新点包括点的个数,从入度为0或出度为0的新点中找出包括点数最小的minnum,再用上面剩余的边ans - minnum*(n-minnum)就是所要的答案。

由于假设不减入度为0或出度为0相关的边,那么该点本身包括有入边和出边。加的边永远都是强连通图。所以仅仅能去掉与入度为0或出度为0点的相关边,仅仅减掉一个方向的边,要么全是(n-minnum)点数到minnum点数的入边,那么是minnum点数到(n-minnum)点数的出边。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll __int64
const int N = 100005;
struct EDG{
    int to,next;
}edg[N];
int eid,head[N];
int low[N],dfn[N],vist[N],num[N],id[N],deep,stack1[N],tn,top;
int in[N],out[N];

void init(){
    eid=tn=top=deep=0;
    memset(head,-1,sizeof(head));
    memset(vist,0,sizeof(vist));
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    memset(num,0,sizeof(num));
}
void addEdg(int u,int v){
    edg[eid].to=v; edg[eid].next=head[u]; head[u]=eid++;
}
void tarjer(int u){
    stack1[++top]=u;
    vist[u]=1;
    deep++;
    low[u]=dfn[u]=deep;
    for(int i=head[u]; i!=-1; i=edg[i].next){
        int v=edg[i].to;
        if(vist[v]==0){
            vist[v]=1;
            tarjer(v);
            low[u]=min(low[u],low[v]);
        }
        else if(vist[v]==1)
            low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        tn++;
        do{
            vist[stack1[top]]=2;
            num[tn]++;
            id[stack1[top]]=tn;
        }while(stack1[top--]!=u);

    }
}
ll solve(int n,int m){
    ll ans=n*(n-1)-m;
    int minnum=N;
    for(int i=1; i<=n; i++)
        if(vist[i]==0)
         tarjer(i);
    if(tn==1) return -1;
    for(int u=1; u<=n; u++)
    for(int i=head[u]; i!=-1; i=edg[i].next){
        int v=edg[i].to;
        if(id[u]!=id[v])
            in[id[v]]++,out[id[u]]++;
    }
    for(int i=1; i<=tn; i++)
    if(in[i]==0||out[i]==0){
        minnum=min(minnum,num[i]);
    }
    ans-=minnum*(n-minnum);

    return ans;
}
int main(){
    int T,n,m,c=0,a,b;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        init();
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&a,&b);
            addEdg(a,b);
        }
        printf("Case %d: %I64d\n",++c,solve(n,m));
    }
}
时间: 2024-10-07 05:50:11

HDU 4635 Strongly connected(强连通)经典的相关文章

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>

[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——————【 强连通、最多加多少边仍不强连通】

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) 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 grap

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

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

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

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

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

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的题解

今天又爆零了,又是又,怎么又是又,爆零爆多了,又也就经常挂嘴边了,看到这句话,你一定很想说一句"",弱菜被骂傻,也很正常啦. 如果你不开心,可以考虑往下看. 翻到E(HDU 4635 Strongly connected)题,这么短的题目,肯定要先看啦.然后D(LightOJ 1229),然后C(ZOJ 2243),然后F(HDU 4711),然后B(CodeForces 385D),然后看A(HDU 3889)好吧,我承认,A题看了一眼就不看了,B题一看是线段什么有点几何的味道就果断