您的位置:首页 > 其它

POJ 1523 浅谈无向图TarJan连通块割顶分割技术

2017-10-12 20:32 441 查看


世界真的很大

昨天晚上还有十分钟的时候开始写这道题,未果

今天上午考试下午讲课晚上好不容易有时间来写这道题,成功

犯了一个小小的错误不必深究

POJ的读入方式怎么这么恶心woc。。

看题先:

description:

无向图求割点和去除割点后连通分量的个数

input:

The input will contain the description of several networks. A network description will consist of pairs of integers, one pair per line, that identify connected nodes. Ordering of the pairs is irrelevant; 1 2 and 2 1 specify the same connection. All node numbers will range from 1 to 1000. A line containing a single zero ends the list of connected nodes. An empty network description flags the end of the input. Blank lines in the input file should be ignored.

output:

For each network in the input, you will output its number in the file, followed by a list of any SPF nodes that exist.

The first network in the file should be identified as “Network #1”, the second as “Network #2”, etc. For each SPF node, output a line, formatted as shown in the examples below, that identifies the node and the number of fully connected subnets that remain when that node fails. If the network has no SPF nodes, simply output the text “No SPF nodes” instead of a list of SPF nodes.

在这种一读就是板子题的东西下,**的出题人把考点放在了读入方式上。。。

想方设法读入完成后,这道题就是一个求割点然后判断每一个割点删去后会把联通图分成多少块

把图转化为DFS树之后相当于答案就是其子树个数+1,因为还有父亲边的方向。根节点需要特判一下,统计其有多少个子树,这个也可以在tarjan里面做到

完整代码:

#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;

struct edge
{
int u,v,last;
}ed[4000010];

int num=0,idx=0,cnt=0,tot=0,flag=1,son=0;
int head[10010],low[10010],dfn[10010],src[10010],fa[10010];

void add(int u,int v)
{
num++;
ed[num].v=v;
ed[num].last=head[u];
head[u]=num;
}

void tarjan(int u)
{
dfn[u]=low[u]=++idx;
for(int i=head[u];i;i=ed[i].last)
{
int v=ed[i].v;
if(i==(fa[u]^1)) continue ;
if(!dfn[v])
{
fa[v]=i;
tarjan(v);
low[u]=min(low[v],low[u]);
if(low[v]>=dfn[u])
{
if(u!=1) src[u]++;
else son++;
}
}
else low[u]=min(low[u],dfn[v]);
}
}

void init()
{
memset(head,0,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(src,0,sizeof(src));
memset(fa,0,sizeof(fa));
num=1,idx=0,cnt=0,flag=1,son=0;
}

int main()
{
while(1)
{
init();
while(1)
{
int u,v;
scanf("%d",&u);
if(!u) break ;
scanf("%d",&v);
add(u,v),add(v,u);
cnt++;
}
if(cnt==0) break ;
tarjan(1);
printf("Network #%d\n",++tot);
if(son>1) src[1]=son-1;
for(int i=1;i<=1000;i++)
if(src[i])
{
flag=0;
printf("  SPF node %d leaves %d subnets\n",i,src[i]+1);
}
if(flag) printf("  No SPF nodes\n");
printf("\n");
}
return 0;
}
/*
EL PSY CONGROO
*/


嗯,就是这样

(P.S. 感觉最近题解越来越水了。。真不是因为我懒得写,只不过都是些板子题。。。主要目的是练手然后总结方法。。233)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: