POJ 2117 Electricity

来源:互联网 发布:淘宝皮质特征 编辑:程序博客网 时间:2024/04/28 13:29

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

题意:就是删去一个点后,整个图最多有几个连通分支。所以明显选择删去之后所形成的连通分支最多的割点。这题可以联系

poj 1523(我的结题报告传送门)http://blog.csdn.net/u010489766/article/details/9336285,关于tarjan算法的详解,我全部都写在那的注释了

注意:

1.图不一定是连通图,可能有多个连通分支。最后的结果要加上图的原本的连通分支。

2.对于全是独立的点的,明显结果是P-1,因为至少要毁掉一个电厂

#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>#define MEM(x,y) memset(x,y,sizeof(x))#define INF 10100using namespace std;int low[INF],deep[INF],sum[INF];vector<int>graph[INF];int dfs_deep,P,C;void tarjan(int node,int prenode){low[node] = deep[node] = ++dfs_deep;int len = graph[node].size();int son = 0;for(int i = 0 ; i < len ; i ++){if(!deep[graph[node][i]]){tarjan(graph[node][i],node);low[node] = min(low[node],low[graph[node][i]]);if(low[graph[node][i]] >= deep[node])sum[node]++;son++;}elseif(graph[node][i] != prenode)low[node] = min(low[node],deep[graph[node][i]]);}if(prenode == -1){if(son >= 2)sum[node] = son;}else if(sum[node] > 0)sum[node] ++;}int main(){while(scanf("%d%d",&P,&C)!= EOF && P != 0){if(C == 0)//如果没边,全是独立的点{printf("%d\n",P-1);continue;}for(int i = 0 ; i < P; i++)graph[i].clear();MEM(deep,0);MEM(low,0);MEM(sum,0);for(int i = 1; i <= C; i ++){int a,b;scanf("%d%d",&a,&b);if(a != b){graph[a].push_back(b);graph[b].push_back(a);}}dfs_deep = 0;int ans = 0;//ans记录整个图原来共有几个连通分支for(int i = 0 ; i < P ; i ++){if(!deep[i]){if(graph[i].size() > 0)tarjan(i,-1);ans++;}}int m = -1;for(int i = 0 ;i < P; i ++)//求删去后形成的最多连通分支的割点数m = max(m,sum[i]);printf("%d\n",ans-1+m);}return 0;}


 

 

原创粉丝点击