题意:给你一个图,问最多能添加多少条边使图仍为不是强连通图,如果原图是强连通输出 ‘-1’
分析:先把求出连通分量进行缩点,因为是求最多的添加边,所以可以看成两部分 x,y,只能一部分向另外一部分连边,内部的就是完全图,所以是x*(x+1)+x*y+y*(y+1)-M,只需要求出来出度或者入度为0的最少点的那个连通分量即可。
**********************************************************************
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN = 1e5+;
const int oo = 1e9; struct Edge{int v, next;}e[MAXN];
int Head[MAXN], cnt;
void AddEdge(int u, int v)
{
    e[cnt].v = v;
    e[cnt].next = Head[u];
    Head[u] = cnt++;
} int dfn[MAXN], low[MAXN], Index;
int Stack[MAXN], top, inStack[MAXN];
int blg[MAXN], bnt, nblg[MAXN];///属于哪个连通分量,连通分量里面有几个点
int outEdge[MAXN], inEdge[MAXN]; void InIt(int N)
{
    cnt = Index = top = bnt = ;
    for(int i=; i<=N; i++)
    {
        Head[i] = -;
        dfn[i] = ;
        nblg[i] = ;
        outEdge[i] = ;
        inEdge[i] = ;
    }
}
void Tarjan(int u)
{
    int v;     low[u] = dfn[u] = ++Index;
    Stack[++top] = u;
    inStack[u] = true;     for(int j=Head[u]; j!=-; j=e[j].next)
    {
        v = e[j].v;
        if( !dfn[v] )
        {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(inStack[v] == true)
            low[u] = min(low[u], dfn[v]);
    }     if(low[u] == dfn[u])
    {
        ++bnt;
        do
        {
            v = Stack[top--];
            inStack[v] = false;
            blg[v] = bnt;
            nblg[bnt]++;
        }
        while(u != v);
    }
} int main()
{
    int T, t=;     scanf("%d", &T);     while(T--)
    {
        int i, j, u, v, N, M;         scanf("%d%d", &N, &M);         InIt(N);         for(i=; i<M; i++)
        {
            scanf("%d%d", &u, &v);
            AddEdge(u, v);
        }         for(i=; i<=N; i++)
        {
            if( !dfn[i] )
                Tarjan(i);
        }         for(i=; i<=N; i++)
        for(j=Head[i]; j!=-; j=e[j].next)
        {
            v = e[j].v;
            if(blg[i] != blg[v])
            {
                inEdge[ blg[v] ]++;
                outEdge[ blg[i] ]++;
            }
        }         int x, y=oo;         for(i=; i<=bnt; i++)
        {
            if(!outEdge[i] || !inEdge[i])
                y = min(y, nblg[i]);
        }         x = N-y;         if(bnt == )
            printf("Case %d: -1\n", t++);
        else
            printf("Case %d: %lld\n",t++, (long long)x*(x-)+x*y+y*(y-)-M);
    }     return ; } 

G - Strongly connected - hdu 4635(求连通分量)的更多相关文章

  1. 强连通图(最多加入几条边使得图仍为非强连通图)G - Strongly connected HDU - 4635

    题目链接:https://cn.vjudge.net/contest/67418#problem/G 具体思路:首先用tarjan缩点,这个时候就会有很多个缩点,然后再选取一个含有点数最少,并且当前这 ...

  2. Strongly connected HDU - 4635(判断强连通图 缩点)

    找出强联通块,计算每个连通块内的点数.将点数最少的那个连通块单独拿出来,其余的连通块合并成一个连通分量. 那么假设第一个连通块的 点数是 x  第二个连通块的点数是 y 一个强连通图(每两个点之间,至 ...

  3. kuangbin专题 专题九 连通图 Strongly connected HDU - 4635

    题目链接:https://vjudge.net/problem/HDU-4635 题目:有向图,给定若干个连通图,求最多还能添加几条边,添完边后,图仍然要满足 (1)是简单图,即没有重边或者自环 (2 ...

  4. Strongly connected HDU - 4635 原图中在保证它不是强连通图最多添加几条边

    1 //题意: 2 //给你一个有向图,如果这个图是一个强连通图那就直接输出-1 3 //否则,你就要找出来你最多能添加多少条边,在保证添加边之后的图依然不是一个强连通图的前提下 4 //然后输出你最 ...

  5. hdu 1213 求连通分量(并查集模板题)

    求连通分量 Sample Input2 //T5 3 //n m1 2// u v2 34 5 5 12 5 Sample Output24 # include <iostream> # ...

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

    Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  7. HDU 4635 Strongly connected (Tarjan+一点数学分析)

    Strongly connected Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  8. HDU 4635 Strongly connected(强连通)经典

    Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  9. hdu 4635 Strongly connected 强连通缩点

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...

随机推荐

  1. jquery之隐藏div

    1.$("#demo").attr("style","display:none;");//隐藏div $("#demo" ...

  2. Python之路,Day22 - 网站用户访问质量分析监测分析项目开发

    Python之路,Day22 - 网站用户访问质量分析监测分析项目开发   做此项目前请先阅读 http://3060674.blog.51cto.com/3050674/1439129  项目实战之 ...

  3. 关于c#流

     C#流的简单认识 前言 本篇文章简单总结了在C#编程中经常会用到的一些流.比如说FileStream.MemoryStream. BufferedStream. NetWorkStream. Str ...

  4. 自定义鼠标Cursor转变成图片

    今天无意做到项目遇到一个好玩的事情,就是当我鼠标移到一个链接上面,并不是像正常那样出现一个小手,而是变成一个小十字架, 下面看图当时第一眼看到总感觉哪里不对,噢噢噢噢 这样的 小手没了,居然是一个图片 ...

  5. 编写利用Fragment创建新闻列表

    编写利用Fragment创建新闻列表 1.创建新闻实体类News,代码如下:   public class News { private String title; private String co ...

  6. for update和for update nowait的区别和使用

    首先,for update 和for update nowait 是对操作的数据行进行加锁,在事务提交前防止其他操作对数据的修改. for update 和for update nowait主要区别在 ...

  7. UITouch触摸事件

    UITouch触摸事件 主要为三个方法 1.-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{2.3. UITouch * ...

  8. [转]Java远程方法调用

    Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远 ...

  9. 你好,C++(9)坐216路公交车去买3.5元一斤的西红柿——C++中如何表达各种数值数据 3.3 数值数据类型

    3.3  数值数据类型 从每天早上睁开眼睛的那一刻开始,我们几乎每时每刻都在与数字打交道:从闹钟上的6点30分,到上班坐的216路公共汽车:从新闻中说的房价跌到了100元每平米到回家买菜时的西红柿3. ...

  10. 谈谈PHP、Python与Ruby

    假如你想帮他尽快找个活儿,赚到钱,推荐PHP. 假如你想让他成为一个高效工程师,推荐 Python. 假如你想让他爱上他的工作,推荐 Ruby. 语言的选择 编程语言非常重要,不要认为他们都图灵等价, ...