POJ 2117 Electricity(无向图割点)
2017-08-24 20:03
344 查看
POJ 2117 Electricity(无向图割点)
http://poj.org/problem?id=2117
题意:
给你一个无向图(不一定连通),现在问你从该图中删除任意一个顶点之后,该无向图所具有的连通分量数目最大是多少?
分析:
本题与前一题不一样,前一题是要你判定哪些点是割点。但是这题需要你求出割点到底能割出几个连通分量。本题的无向图可能不连通。我们只需要考虑在同一个连通分量时,一个割点到底能把图割成几部分即可。
在dfs的时候,我们用cut[i]==X表示在dfs树中当i节点被删除时,i节点的X个儿子被切割开来(可以认为cut[i]是i节点与它的儿子连接的桥边的数目)。注意:如果i是根且其儿子只有1个,虽然i不是割点,cut[i]依然=1。如果i节点非割点,那么cut[i]=0。如果i是割点,那么cut[i]就是i被删除后将割出来的儿子数目。
然后我们求出了每个点的cut[i]值,即i点被删除,会有cut[i]个儿子树被割出来。如果i是dfs树的非根节点,那么cut[i]== 切除i之后增加的连通分量数目。如果i是dfs树的根节点,那么cut[i]-1才是切除i之后增加的连通分量数目(想想是不是)。
如果原始cut[i]=0,表示i是孤立的一点,此时cut[i]-1=-1.
如果原始cut[i]=1,表示i为根且有一个儿子,此时cut[i]-1=0.
如果原始cut[i]>=2,表示i为根且分割了>=2个儿子,此时cut[i]-1>=1.
(以上含义需仔细体会验证)
AC代码:
http://poj.org/problem?id=2117
题意:
给你一个无向图(不一定连通),现在问你从该图中删除任意一个顶点之后,该无向图所具有的连通分量数目最大是多少?
分析:
本题与前一题不一样,前一题是要你判定哪些点是割点。但是这题需要你求出割点到底能割出几个连通分量。本题的无向图可能不连通。我们只需要考虑在同一个连通分量时,一个割点到底能把图割成几部分即可。
在dfs的时候,我们用cut[i]==X表示在dfs树中当i节点被删除时,i节点的X个儿子被切割开来(可以认为cut[i]是i节点与它的儿子连接的桥边的数目)。注意:如果i是根且其儿子只有1个,虽然i不是割点,cut[i]依然=1。如果i节点非割点,那么cut[i]=0。如果i是割点,那么cut[i]就是i被删除后将割出来的儿子数目。
然后我们求出了每个点的cut[i]值,即i点被删除,会有cut[i]个儿子树被割出来。如果i是dfs树的非根节点,那么cut[i]== 切除i之后增加的连通分量数目。如果i是dfs树的根节点,那么cut[i]-1才是切除i之后增加的连通分量数目(想想是不是)。
如果原始cut[i]=0,表示i是孤立的一点,此时cut[i]-1=-1.
如果原始cut[i]=1,表示i为根且有一个儿子,此时cut[i]-1=0.
如果原始cut[i]>=2,表示i为根且分割了>=2个儿子,此时cut[i]-1>=1.
(以上含义需仔细体会验证)
AC代码:
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; const int maxn=10000+10; int n,m; vector<int> G[maxn]; int cut[maxn]; int low[maxn]; int pre[maxn]; int dfs_clock; int tarjan(int u,int fa) { int lowu= pre[u]=++dfs_clock; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!pre[v])//子节点 且没有计算过 { int lowv=tarjan(v,u); lowu=min(lowv,lowu); if(lowv>=pre[u]) cut[u]++; } else if(pre[v]<pre[u] && v!=fa)//计算过 且有反向边 lowu = min(lowu,pre[v]); } return low[u]=lowu; } int main() { while(scanf("%d%d",&n,&m)==2&&n) { dfs_clock=0; memset(cut,0,sizeof(cut)); memset(pre,0,sizeof(pre)); for(int i=0;i<n;i++) G[i].clear(); 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 sum=0;//计数连通分量数目 int max_cut=-10000; for(int i=0;i<n;i++)if(!pre[i]) { //cut 不是关键节点的结点为0 //关键节点记录他的子树数量(桥边的数目) //对根节点特判 因为他没有父节点 所有如果从根节点断开 //增加的联通量的数量为子树的数量减1 sum++; tarjan(i,-1); cut[i]--; } for(int i=0;i<n;i++) max_cut=max(max_cut,cut[i]); printf("%d\n",sum+max_cut); } return 0; }
相关文章推荐
- POJ 2117 Electricity(无向图割点) && HDU 4587 TWO NODES
- poj 2117 Electricity 【无向图求割点】【求去掉一个点后 图中最多的BCC数目】
- poj 2117 Electricity 求无向图中去掉一个点后最大的联通分支数 无向图有可能不联通 tarjan求割点模板
- POJ 2117 Electricity(无向图割点)
- POJ 2117 Electricity(无向图割点)
- poj 2117 Electricity (无向图割点去除后最大连通分支数)
- POJ 2117 Electricity (无向图求割点)
- POJ 2117 Electricity(割点)
- POJ 2117 Electricity
- poj 2117(tarjan 求无向图去掉一点的连通分量)
- POJ 2117 Electricity
- POJ 2117 Electricity
- POJ 2117 Electricity
- POJ 2117 Electricity(割点求连通分量)
- 【POJ】2117 Electricity
- POJ 2117 Electricity (tarjan)删割点后求块数
- POJ 2117 Electricity
- poj 2117 Electricity
- POJ 2117 Electricity
- poj2117 Electricity