HDU 4587 无向图的割点

TWO NODES

Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1137    Accepted Submission(s): 333

Problem Description

Suppose that G is an undirected graph, and the value of stab is defined as follows:

Among the expression,G-i, -j is the remainder after removing node i, node j and all edges that are directly relevant to the previous two nodes. cntCompent is the number of connected components of X independently.
Thus, given a certain undirected graph G, you are supposed to calculating the value of stab.

Input

The input will contain the description of several graphs. For each graph, the description consist of an integer N for the number of nodes, an integer M for the number of edges, and M pairs of integers for edges (3<=N,M<=5000).
Please note that the endpoints of edge is marked in the range of [0,N-1], and input cases ends with EOF.

Output

For each graph in the input, you should output the value of stab.

Sample Input

4 5

0 1

1 2

2 3

3 0

0 2

Sample Output

2

题目意思:

一个无向图,有n个结点m条边,求删除两个结点剩下图中连通分量最多为多少个。

思路:

该题限制时间为12MS,不用多想了,暴力吧。。枚举删除的第一个结点,然后求出剩下图中割点及其儿子个数(即为删除该割点后多出的连通分量数),不断更新最大值。思路很简单,代码细节很多,wa了很多次。。。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 using namespace std;
 8
 9 #define N 5005
10
11 vector<int>ve[N];
12 int dfn[N], low[N], visited[N];
13 int gd[N];
14 int n, m, dfn_clock, lt_num, root, son, del;
15
16 void tarjan(int u,int fa){
17     if(u==del) return;           //删除第一个点
18     int i, j, k;
19     dfn[u]=low[u]=dfn_clock++;
20     visited[u]=1;
21     for(i=0;i<ve[u].size();i++){
22         int v=ve[u][i];
23         if(v==del) continue;         //删除第一个点
24         if(v==fa) continue;
25         if(!visited[v]){
26             tarjan(v,u);
27             low[u]=min(low[u],low[v]);
28             if(u==root) son++;
29             else if(low[v]>=dfn[u]) gd[u]++;   //对应割点儿子数目+1
30         }
31         else low[u]=min(low[u],dfn[v]);
32     }
33 }
34
35 main()
36 {
37      int i, j, k, x, y;
38      while(scanf("%d %d",&n,&m)==2){
39          for(i=0;i<=n;i++) ve[i].clear();
40          while(m--){
41              scanf("%d %d",&x,&y);
42              ve[x].push_back(y);
43              ve[y].push_back(x);
44          }
45          int ans=-1;
46          for(i=0;i<n;i++){         //枚举第一个删除的点
47              memset(visited,0,sizeof(visited));
48              memset(dfn,0,sizeof(dfn));
49              memset(gd,0,sizeof(gd));
50              visited[i]=1;
51              dfn_clock=lt_num=son=0;
52              del=i;
53              int maxson=0;
54
55              for(j=0;j<n;j++){     //从剩下图中找删除的另一个点,另一个点必是割点
56                  if(!visited[j]){
57                      lt_num++;
58                  //    visited[j]=1;
59                      root=j;
60                      tarjan(j,-1);
61                      maxson=max(maxson,son);
62                      son=0;
63                  }
64              }
65              if(lt_num==n-1) lt_num--;      //在这wa了很多次,试试这个数据:5 0
66              for(j=0;j<n;j++) ans=max(ans,gd[j]+lt_num);
67              ans=max(ans,maxson+lt_num-1);
68          }
69          printf("%d\n",ans);
70      }
71 }
时间: 2024-10-23 22:42:22

HDU 4587 无向图的割点的相关文章

HDU 4587 TWO NODES 割点

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4587 题意: 删除两个点,使连通块的数目最大化 题解: 枚举删除第一个点,然后对删除了第一个点的图跑割点更新答案. 代码: #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> using namespace std; c

hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有的连通分量只有一个点,当舍去该点时候,连通分量-1: 复习求割点的好题! #include<iostream> #include<cstdio> #include<vector> using namespace std; int n,m; vector<vector&

hdu 4587 判断孤立点+割点+ 删除点之后,剩下多少连通分量

做了很久...... 题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4587 先枚举删除的第一个点,第二个点就是找割点,没有割点当然也有答案 学到的: 1.图论硬套模板不太现实,比如这道题,我能想到孤立点是特殊情况,删除孤立点,连通分支个数会减少一,但是一直处理不好,最后按缩点的做法搞了, 判断是不是孤立点的方法: 就是先用一个数组scnt[i]=j,vv[j]++  表示点i在以j为祖先的联通分支里,而且每次都让vv[j]++,就使得vv[j

UVA 315 Network(无向图求割点)

题目大意 A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N. No two places have the same number. The lines are bidirectional and always connect together two pl

hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs

题意如标题所述, 先无向图缩点,统计出每个bcc权,建新图,然后一遍dfs生成树,标记出每个点(新图)以及其子孙的权值之和.这样之后就可以dfs2来枚举边(原图的桥),更新最小即可. 调试了半天!原来是建老图时候链式前向星和新图的vector<vector< int>>俩种存图搞乱了!!!不可原谅!哎!愚蠢!愚不可及!提交后1A. 后来百度之后,发现说是用树形dp,看了代码解法,竟然和我的是一样的算法..原来这种算法可以叫树形dp...的确有点dp味道..不过感觉不太浓.. 以后多

POJ 1144 无向图的割点

Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10207   Accepted: 4744 Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N

Uva 315 求无向图的割点的个数

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=251 A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to 

求无向图的割点和桥

/** * 求 无向图的割点和桥 * 可以找出割点和桥,求删掉每个点后增加的连通块. * 需要注意重边的处理,可以先用矩阵存,再转邻接表,或者进行判重 * 调用solve输出割点数,全局变量bridge记录边的个数 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; const int maxn=1001

hdu 4738 无向图缩点断桥 // 细节坑题

Caocao's Bridges 题意:给个无向图,求出边权最小的桥. 一看,直接缩点,若无桥,输出-1,有桥,遍历下边,更新最小..分分钟搞定,以为IA的..一交wa... 坑点:1:若原图不连通,则无须派人去!输出0!: 2:若桥的权是0,则还有派一个人把炸弹拿去,输出1! 3:有重边.(按多条边算). 哎!记住这个教训!以后做题 1:考虑边界或者特殊数据!(边权为0!n==1等) 2:考虑原图连通性!(这次考虑了原图就强连通..没有考虑根本不连通!) 3:重边.这题的重边是按重边算(不是一