首页 > 其他分享 >POJ2117 Electricity 题解 tarjan点双连通分量 割点

POJ2117 Electricity 题解 tarjan点双连通分量 割点

时间:2023-06-14 12:34:50浏览次数:42  
标签:tarjan 点双 int 题解 ts dfn maxn low

题目链接:http://poj.org/problem?id=2117

题目大意:

给定一个由 \(n\)个点 \(m\) 条边构成的无向图,请你求出该图删除一个点之后,连通块最多有多少。

解题思路:

tarjan,判断 \(u\) 的子节点有几个 \(v\) 满足 \(low[v] \ge dfn[u]\) 就是答案,但是同时如果 \(u\) 不是这个 dfs 树的根节点,个数还要加 \(1\)。

示例程序1(C++11,POJ不支持):

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;

int n, m, dfn[maxn], low[maxn], ts, ans, root;
vector<int> g[maxn];

void init() {
    for (int i = 0; i < n; i++) g[i].clear(), dfn[i] = low[i] = 0;
    ts = ans = 0;
}

void tarjan(int u, int p) {
    dfn[u] = low[u] = ++ts;
    int cnt = 0;
    for (auto v : g[u]) {
        if (v != p) {
            if (!dfn[v]) {
                tarjan(v, u), low[u] = min(low[u], low[v]);
                if (dfn[u] <= low[v])
                    cnt++;
            }
            else
                low[u] = min(low[u], dfn[v]);
        }
    }
    if (u != root) cnt++;
    ans = max(ans, cnt);
}

int main() {
    while (~scanf("%d%d", &n, &m) && n) {
        init();
        for (int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        int cnt = 0;
        for (root = 0; root < n; root++)
            if (!dfn[root])
                cnt++, tarjan(root, -1);
        printf("%d\n", ans + cnt - 1);
    }
    return 0;
}

示例程序2(POJ支持):

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
const int maxn = 10010;

int n, m, dfn[maxn], low[maxn], ts, ans, root;
vector<int> g[maxn];

void init() {
    for (int i = 0; i < n; i++) g[i].clear(), dfn[i] = low[i] = 0;
    ts = ans = 0;
}

void tarjan(int u, int p) {
    dfn[u] = low[u] = ++ts;
    int cnt = 0;
    int sz = g[u].size();
    for (int i = 0; i < sz; i++) {
        int v = g[u][i];
        if (v != p) {
            if (!dfn[v]) {
                tarjan(v, u), low[u] = min(low[u], low[v]);
                if (dfn[u] <= low[v])
                    cnt++;
            }
            else
                low[u] = min(low[u], dfn[v]);
        }
    }
    if (u != root) cnt++;
    ans = max(ans, cnt);
}

int main() {
    while (~scanf("%d%d", &n, &m) && n) {
        init();
        for (int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        int cnt = 0;
        for (root = 0; root < n; root++)
            if (!dfn[root])
                cnt++, tarjan(root, -1);
        printf("%d\n", ans + cnt - 1);
    }
    return 0;
}

标签:tarjan,点双,int,题解,ts,dfn,maxn,low
From: https://www.cnblogs.com/quanjun/p/17479845.html

相关文章

  • CF1697F 题解
    题意传送门构造一个长度为\(n\)的数列\(a\),满足\(1\lea_i\lek\)且\(a\)不降,以及\(m\)个约束,有三种情况:1ix,表示\(a_i\nex\)2ijx,表示\(a_i+a_j\lex\)3ijx,表示\(a_i+a_j\gex\)无解输出\(-1\)。\(1\len,m\le2\times10^4,2\lek\le10\)。题......
  • 【Android】ListView与Button的共存问题解决
    【Android】ListView与Button的共存问题解决这两天在捣鼓ListViewwidget,为了在ListView中加入Button这类的有“点击”事件的widget,请教了不少高手,感谢LandMark对我的认真讲解,下面把解决过程描述一下。 ListView和其它能触发点击事件的widget无法一起正常工作的......
  • P2860 [USACO06JAN]Redundant Paths G 题解 ratjan边双连通分量
    题目链接:https://www.luogu.com.cn/problem/P2860题目大意:给定一个无向连通图,求至少加几条边,能使其变成一个边双连通图。解题思路:边双连通分量缩点后计算度数为\(1\)的节点个数,假设有\(cnt\)个,则答案为\((cnt+1)/2\)。示例程序:#include<bits/stdc++.h>usingnamespac......
  • Educational Codeforces Round 150 (Rated for Div. 2) 题解
    https://codeforces.com/contest/1841https://codeforces.com/contest/1841/problemsD.PairsofSegmentshttps://codeforces.com/contest/1841/problem/D因为\(n\)只有\(2000\),所以考虑枚举每一对\((i,j)\)满足区间有交集并且\(i\neqj\)。如果有交集,就合并。然后......
  • 题解 P9196【[JOI Open 2016] 销售基因链】
    套路题,来讲个套路解法。如果没有后缀的要求,答案就是trie树的子树内字符串数量。现在加上了后缀,尝试继续使用trie树解决问题。我们建立两棵trie树\(T_1,T_2\),其中\(T_1\)是正常的trie树,\(T_2\)是每个字符串翻转后的trie树。这样的话,包含给定后缀的字符串在\(T_2\)......
  • C++ Windows.h max宏与std::max冲突问题解决
    C语言引入的宏支持了一定程度的元编程,但它仅仅是简单的字符串替换,这种“六亲不认”的操作很容易导致一些编译错误。这篇文章介绍了一种场景:项目同时引入了老的C头文件,里面用宏定义了一些宏函数;还引入了C++的头文件,里面用其他方式定义了一些同名函数。具体到问题本身,这个......
  • Not Another Linear Algebra Problem 题解
    题意:自己看。首先我们知道我们唯一能找到的题解在hos_lyric的代码里。把它放在这里:(由bikuhiku提供)\[\begin{aligned}&U\subseteq\mathbb{F}_p^n,\text{subspace}\\&a(U):=\#\{p\in\text{Aut}(\mathbb{F}_p^n)|\text{Ker}(p-\text{id})=U\}\\&b(U):=......
  • 【问题解决1】fatal error: X11/XXXX.h: No such file or directory
    问题现象编译鸿蒙代码时,报如下类似的错误:错误1:错误2:解决方法step1:安装依赖文件sudoapt-getinstallapt-filesudoapt-fileupdatestep2:查找报错文件apt-filesearchXXXX.h例如:报错的是Intrinsic.h或上图中的Xrandr.h,对应如下:apt-filesearchIntrinsic......
  • vue调用百度api时,跨域问题解决方案
    最近在调用百度地图,文字转语音接口的时候,用vue,js来前端实现转换,及时语音播报,遇到点问题;1.之前直接不用accessToken,一个连接拼接抓取的,已经失效了。2.查看百度文档,更新后的接口,按照文档nodejs格式,一直都是报跨域问题,单独在headers中加'Access-Control-Allow-Origin':'*'无效。......
  • [ABC305C] Snuke the Cookie Picker题解
    题目大意有一个\(H\timesW\)的网格,一种有一个矩形,矩形中间有一个点被挖空,求这个点的坐标。(.表示空白,#表示矩形内的点)解析观察我们可以发现,每一矩形内的个点上下左右至少会有两个是#。如图:而每一个在矩形外的点上下左右最多只有一个#。所以我们只需要找的一个.的上......