POJ 1523 SPF(割点,分块,tarjan)

来源:互联网 发布:js和jquery书籍 编辑:程序博客网 时间:2024/05/22 02:20

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

题目大意:问你图中有哪些割点,并且这些割点能将图分成几块

思路:因为是无向图且没有重边,tarjan判断下是否为割点就可以了,如果

是根节点,且根节点有多于一棵子树,则根节点是割点,若不是根节点且

存在u的孩子使得dfn[u]<=low[v],则u是割点,根节点是割点分割成的部分

是子树的个数,其他是孩子个数加上父亲的个数,也就是孩子数+1

上代码:


#include<iostream>#include<cmath>#include<cstring>#include<string>#include<cstdio>#include<queue>#include<stack>#include<vector>#include<algorithm>using namespace std;#define inf 0x3f3f3f3f#define mod 1e9+7#define ll long long#define maxn 1000+10vector<int>G[maxn];bool visit[maxn];int dfn[maxn], low[maxn], child[maxn];int index, son;void tarjan(int u)//连通只做一次不用循环{dfn[u] = low[u] = ++index;visit[u] = true;for (int i = 0; i < G[u].size(); i++){int v = G[u][i];if (!visit[v]){tarjan(v);low[u] = min(low[u], low[v]);if (dfn[u] <= low[v]){if (u != 1)//非根节点,根节点可以选取任意一个child[u]++;elseson++;}}else//存在返回父节点的,不返回父节点的做法也可以low[u] = min(low[u], dfn[v]);}}void solve(){memset(visit, false, sizeof(visit));memset(child, 0, sizeof(child));index = 0;son = 0;tarjan(1);//因为是连通的,所以只做一次tarjan}int main(){//freopen("Text.txt", "r", stdin);int a, b;int k = 1;while (1){while (scanf("%d", &a) && a)//无重边的{scanf("%d", &b);G[a].push_back(b);G[b].push_back(a);}if (k > 1)printf("\n");solve();printf("Network #%d\n", k++);bool flag = true;child[1] = son - 1;for (int i = 1; i < maxn; i++){if (child[i] > 0){flag = false;printf("  SPF node %d leaves %d subnets\n", i, child[i] + 1);}}if (flag)printf("  No SPF nodes\n");for (int i = 1; i <= 1000; i++)G[i].clear();scanf("%d", &a);if (!a)break;scanf("%d", &b);G[a].push_back(b);G[b].push_back(a);}return 0;}


原创粉丝点击