POJ 2117 (割点+连通分量)

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

题目大意:在一个非连通图中,求一个切除图中任意一个割点方案,使得图中连通分量数最大。

解题思路

一个大陷阱,m可以等于0,这时候要特判,结果就是n-1。

同时出题者脑子秀逗了,也不给C的范围。我开了两倍点大小RE了,于是怒开了五倍点大小才A了。

本题不是连通图,需要先计算原始图中的连通分量。方法就是dfs染色。

然后dfs求割点。

之后枚举割点,由于是非连通图,所以连通分量数=原始分量数+block-1。

-1的原因是,每次相当于对其中一个连通分量计算,加上新的block之后,所以要减-1。

#include "cstdio"
#include "cstring"
#include "vector"
using namespace std;
#define maxn 10005
struct Edge
{
    int to,next;
}e[maxn*5];
int dfs_clock,pre[maxn],block,head[maxn],tol;
bool cut[maxn],vis[maxn];
void addedge(int u,int v)
{
    e[tol].to=v;
    e[tol].next=head[u];
    head[u]=tol++;
}
int dfs(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock;
    int child=0;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        if(!pre[v])
        {
            int lowv=dfs(v,u);
            lowu=min(lowu,lowv);
            if(lowv>=pre[u]) cut[u]=true;
        }
        else if(pre[v]<pre[u]&&v!=fa) lowu=min(lowu,pre[v]);
    }
    if(fa<0&&child==1) cut[u]=false;
    return lowu;
}
void check(int u,int fa)
{
    vis[u]=true;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        if(!vis[v])
        {
            if(u==fa) block++;
            check(v,fa);
        }
    }
}
void link(int u) //判断初始连通分量
{
    vis[u]=true;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].to;
        if(!vis[v]) link(v);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    while(scanf("%d%d",&n,&m)&&n)
    {
        memset(head,-1,sizeof(head));
        memset(pre,0,sizeof(pre));
        memset(cut,false,sizeof(cut));
        dfs_clock=0;tol=0;
        if(m==0) printf("%d\n",n-1); //特判
        else
        {
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d",&u,&v);
                addedge(u,v);
                addedge(v,u);
            }
            int res=0,tt=0;
            for(int i=0; i<n; i++) if(!vis[i]) {tt++;link(i);}
            memset(vis,false,sizeof(vis));
            for(int i=0; i<n; i++) if(!pre[i])  dfs(i,-1);
            res=tt;
            for(int i=0; i<n; i++)
            {
                if(cut[i])
                {
                    check(i,i);
                    if(tt) res=max(res,block+tt-1);
                    block=0;
                    memset(vis,false,sizeof(vis));
                }
            }
            printf("%d\n",res);
        }
    }
}
2905876 neopenx POJ 2117 Accepted 732 2422 C++ 2129  
时间: 2024-10-20 16:13:35

POJ 2117 (割点+连通分量)的相关文章

poj 2117 Electricity(tarjan求割点删掉之后的连通块数)

题目链接:http://poj.org/problem?id=2117 题意:求删除一个点后,图中最多有多少个连通块. 题解:就是找一下割点,根节点的割点删掉后增加son-1(son为子树个数),非根节点删掉之后++ #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 1e4 + 10; const int M = 1e6 + 10; st

POJ 2117 求无向图的割点

Electricity Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4332   Accepted: 1419 Description Blackouts and Dark Nights (also known as ACM++) is a company that provides electricity. The company owns several power plants, each of them sup

poj 2117 Electricity 【无向图求割点】【求去掉一个点后 图中最多的BCC数目】

Electricity Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4597   Accepted: 1515 Description Blackouts and Dark Nights (also known as ACM++) is a company that provides electricity. The company owns several power plants, each of them sup

SPF(poj 1523) 割点入门

1 /***************************************** 2 SPF(poj 1523) 3 割点入门 4 http://poj.org/problem?id=1523 5 6 ******************************************/ 7 8 #include<iostream> 9 #include<algorithm> 10 #include<cstdio> 11 #include<cstring&

poj 2524 求连通分量(并查集模板题)

求连通分量 Sample Input 10 91 21 31 41 51 61 71 81 91 1010 42 34 54 85 80 0Sample Output Case 1: 1Case 2: 7 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # include

POJ 2117 Electricity

Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5573   Accepted: 1818 Description Blackouts and Dark Nights (also known as ACM++) is a company that provides electricity. The company owns several power plants, each of them supplying a sma

poj 1144 割点

最基本的求割点的题目,建议深入理解该dfs的过程,还有就是对于同一个点来说,满足它是割点的条件可能会成立多次,所以一定要在dfs结束后统计割点个数,而不是在dfs的过程中实现. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 200; 7 const int M = 500; 8 int dfn[N]; 9 in

A - Network of Schools - poj 1236(求连通分量)

题意:学校有一些单向网络,现在需要传一些文件,1,求最少需要向几个学校分发文件才能让每个学校都收到,2,需要添加几条网络才能在任意一个学校分发都可以传遍所有学校. 分析:首先应该求出来连通分量,进行缩点,然后求每个分量的入度和出度,入度等于0的很明显都需要分发一个文件,至于需要添加几条边可以成为一个强连通,就是出度和入度最大的那个,因为需要把出度和入度相连. **************************************************************** #inc

poj 2117 Electricity【点双连通求删除点后最多的bcc数】

Electricity Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4727   Accepted: 1561 Description Blackouts and Dark Nights (also known as ACM++) is a company that provides electricity. The company owns several power plants, each of them sup