POJ 1523
Tarjan找割点,分成的部分就是该点的子树个数加1(根要特判)
输入输出方式好恶心呀。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 11000
using namespace std;
int to[N*10],cnt,nxt[N*10],head[N],vis[N],low[N],dfn[N],now;
int ans,z[N],top,n,m,in[N],k,rt[N],p[N],flag,d[N];
void add(int x,int y){
to[++cnt]=y;
nxt[cnt]=head[x];
head[x]=cnt;
}
void dfs(int x){
vis[x]=1;dfn[x]=low[x]=++now;
z[++top]=x;in[x]=1;
for(int i=head[x];i;i=nxt[i]){
if(vis[to[i]]){
if(in[to[i]]) low[x]=min(low[x],dfn[to[i]]);
}else {
dfs(to[i]);if(dfn[x]<=low[to[i]])p[x]=1,d[x]++;
low[x]=min(low[x],low[to[i]]);
}
}
}
int main(){
int x,y;
for(int c=1;;c++){
flag=cnt=top=0;
memset(vis,0,sizeof(vis));
memset(z,0,sizeof(z));
memset(d,0,sizeof(d));
memset(p,0,sizeof(p));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(head,0,sizeof(head));
memset(rt,0,sizeof(rt));
for(k=1,n=0;;k++){
scanf("%d",&x);
if(k==1&&x==0) return 0;
if(x==0) break;
scanf("%d",&y);
add(x,y);
add(y,x);
n=max(max(x,y),n);
}printf("Network #%d\n",c);
for(int i=1;i<=n;i++) if(!vis[i]) rt[i]=1,dfs(i);
for(int i=1;i<=n;i++) if(p[i]&&d[i]-rt[i]>0) printf(" SPF node %d leaves %d subnets\n",i,d[i]-rt[i]+1),flag=1;
if(!flag) printf(" No SPF nodes\n");
printf("\n");
}
for(int i=1;i<=n;i++) if(!vis[i])
dfs(i);
printf("%d",ans);
}
posted on 2019-05-19 10:12 啊啊啊起个什么名字好 阅读(102) 评论(0) 编辑 收藏 举报