Gym - 100712H Bridges

沉迷于连通分量了
最后一道了 ,o((>ω< ))o
不知道为什么乍看这道题感觉还挺简单,结果又是一个边连通分量+树的直径问题
树的直径已经被虐过一道了,真的难受T.T~

H. Bridges
An edge in an undirected graph is a ​ bridge​ if after removing it the graph will be disconnected.
Given an undirected connected graph, you are allowed to add one edge between any pair of nodes so that the total number of bridges in the graph is minimized.

Input
The first line of input contains ​ T (1 ≤ T ≤ 64) that represents the number of test cases.
The first line of each test case contains two integers: ​ N (3 ≤ N ≤ 100,000) and ​ M (N-1 ≤ M ≤ 100,000), where ​ N is the number of nodes, and ​ M is the number of edges.
Each of the following ​ M lines contains two space-separated integers: ​ X Y (1 ≤ X, Y ≤ N)(X ≠ Y) , which means that there is an edge between node ​ X
​ and node ​ Y.
It is guaranteed that each pair of nodes is connected by at most one edge.
Test cases are separated by a blank line.
Output
For each test case, print a single line with the minimum possible number of bridges after adding one edge.

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

3 3
1 2
2 3
3 1

Sample Output

1
0

这个题其实比上一道还要简单一点
只需要求出缩点后点的数量 - 树的直径的长度

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#define LL long long
using namespace std;
const int maxn = 100010;
const LL inf = 0xffffffffff;
int n,m;
int dfn[maxn],low[maxn],belong[maxn];
int cnt,index;
struct node
{
    int u,v,w;
}s[maxn];
vector<int >G[maxn];
vector<node> g[maxn];
stack<int >S;
void init()
{
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(belong,0,sizeof(belong));
    for(int i=0;i<=n;i++)
    {
        G[i].clear();g[i].clear();
    }
    cnt = index = 0;
}
void Tarjan(int u,int pre)
{
    dfn[u] = low[u] = ++index;
    S.push(u);
    for(int i=0;i<G[u].size();i++)
    {
        int v = G[u][i];
        if(v == pre)  continue;
        if(!dfn[v])
        {
            Tarjan(v,u);
            low[u] = min(low[u],low[v]);
        }
        else low[u] = min(low[u],dfn[v]);
    }
    if(low[u] == dfn[u])
    {
        int gg;
        ++cnt;
        while(1)
        {
            gg = S.top();
            S.pop();
            belong[gg] = cnt;
            if(gg==u)  break;
        }
    }
}



int max_len,st;

void TreeDia(int u,int pre,int len)
{
    if(len > max_len) st = u,max_len = len;
    for(int i=0;i<g[u].size();i++)
    {
        int v = g[u][i].v;
        if(v==pre)  continue;
        TreeDia(v,u,len+g[u][i].w);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i = 0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            s[i].u = a,s[i].v = b,s[i].w = 1;
            G[a].push_back(b);
            G[b].push_back(a);
        }
        Tarjan(1,-1);

        for(int i=0;i<m;i++)
        {

                int u = belong[s[i].u];
                int v = belong[s[i].v];
                int w = s[i].w;
                if(u!=v)
                {
                    //printf("u = %d,v = %d\n",u,v);
                    g[u].push_back((node){0,v,w});
                    g[v].push_back((node){0,u,w});
                }

        }
        max_len = -1;
        TreeDia(1,-1,0);
        TreeDia(st,-1,0);
        //printf("cnt = %d , max_len = %d\n",cnt,max_len);
        printf("%d\n",cnt-max_len-1);
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 不知道为什么,想起你的第一反应就是你身上的味道。低沉但又有一层清新,浮在你的皮肤表面,嗅到就会觉得无比放松。闻多了...
    小小A酱阅读 1,810评论 0 0
  • 这几天身体不适,在客栈修养生息,也没怎么出去溜达,客栈有很多朋友,和她们一起聊天,有的是刚从尼泊尔回来,有的正...
    压缩水果阅读 1,814评论 2 1
  • 01 今天下午跑到书店去闲晃,看到《断舍离》。 最初接触到这几个字,是在微信公众号里偶心态尔几篇文章的标题,但我一...
    蒸饺阅读 3,077评论 3 1

友情链接更多精彩内容