POJ 1523 SPF 解题报告
Posted icode-xiaohu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1523 SPF 解题报告相关的知识,希望对你有一定的参考价值。
思路:使用tarjan算法求出割点,在枚举去掉每一个割点所能形成的联通块的个数。
注意:后来我看了下别的代码,发现我的枚举割点的方式是比较蠢的方式,我们完全可以在tarjan过程中把答案求出来,引入一下讨论:
如果这个割点是根节点,在tarjan算法中搜到几个孩子结点(low[v] >= dfn[u]),他就能割出几个联通块,如果这个割点是孩子结点,那么他所形成的联通块的个数+1,因为他还有一条与父亲结点间接或直接相连的边。
代码如下:
#include<map> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define maxn 1010 struct EDGE { int to,nxt; } edge[maxn*10]; int head[maxn],low[maxn],dfn[maxn],mark[maxn],vis[maxn]; int tot,all,son,start,tail; void add_edge(int u,int v) { edge[tot].to = v; edge[tot].nxt = head[u]; head[u] = tot++; } void init() { memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(mark,0,sizeof(mark)); all = 0; son = 0; } void tarjan(int u,int fa) { dfn[u] = low[u] = ++all; for(int i = head[u]; i != -1; i = edge[i].nxt) { int v = edge[i].to; if(!dfn[v]) { tarjan(v,u); low[u] = min(low[v],low[u]); if(low[v] >= dfn[u]) { if(u == start) son++; else mark[u] = 1; } } else if(v != fa) low[u] = min(low[u],dfn[v]); } return ; } void bfs(int x,int cant) { queue<int>que; while(!que.empty()) que.pop(); que.push(x); vis[x] = 1; while(!que.empty()) { int num = que.front(); que.pop(); for(int i = head[num]; i != -1; i = edge[i].nxt) { int v = edge[i].to; if(v != cant && !vis[v]) { que.push(v); vis[v] = 1; } } } return ; } int main() { int a,b; int ca = 0; while(~scanf("%d",&a)) { if(!a) break; start = 0,tail = 0; scanf("%d",&b); start = min(a,b); tail = max(a,b); tot = 0; memset(head,-1,sizeof(head)); add_edge(a,b); add_edge(b,a); while(~scanf("%d",&a)) { if(!a) break; scanf("%d",&b); add_edge(a,b); add_edge(b,a); start = min(min(a,b),start); tail = max(max(a,b),tail); } init(); tarjan(start,-1); if(son >= 2) mark[start] = 1; int subnets = 0,spf = 0; printf("Network #%d\n",++ca); bool flag = true; for(int i = start; i <= tail; i++) { if(mark[i]) { flag = false; printf(" SPF node %d leaves ",i); memset(vis,0,sizeof(vis)); subnets = 0; for(int j = start;j <= tail;j++) { if(j == i) continue; if(!vis[j]) { subnets++; bfs(j,i); } } printf("%d subnets\n",subnets); } } if(flag) puts(" No SPF nodes"); puts(""); } return 0; }
以上是关于POJ 1523 SPF 解题报告的主要内容,如果未能解决你的问题,请参考以下文章