poj 1523 SPF
http://poj.org/problem?id=1523
题目大意:给定一个图,求这个图的割点,以及把该割点去掉以后的图有多少过连通分量。
思路:先求出所有的割点,然后暴力枚举这些割点求连通分量(1000个点)。

#include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<bitset> #include<string> #include<climits> #include<cstdio> #include<vector> #include<utility> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define IN puts("in") #define OUT puts("out") #define FR(x) freopen(x,"r",stdin) #define FW(x) freopen(x,"w",stdout) #define ST system("pause") using namespace std; const int maxn = 1005; struct nd { int u,v,next; }edge[maxn*1000]; int head[maxn],vis[maxn],dfn[maxn],low[maxn],gone[maxn]; int ecnt,cnt,idx,tot,n,cas; void add(int u,int v) { edge[ecnt].u = u; edge[ecnt].v = v; edge[ecnt].next = head[u]; head[u] = ecnt++; } void tarjan(int pre,int u) { int i,v; dfn[u] = low[u] = ++idx; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(v==pre)continue; if(!dfn[v]){ tarjan(u,v); low[u] = min(low[v],low[u]); if(low[v]>=low[u]) vis[u] = 1; }else low[u] = min(dfn[v],low[u]); } } void dfs(int pre,int u) { int i,v; if(gone[u]||pre==u)return; gone[u] = 1; for(i = head[u]; i != -1; i = edge[i].next) dfs(u,edge[i].v); } int sovle() { int i,j,k,u,v,flag = 0; scanf("%d",&u); if(!u)return 0; printf("Network #%d\n",++cas); n = 0; memset(vis,0,sizeof(vis)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(head,-1,sizeof(head)); ecnt = cnt = idx = 0; do{ scanf("%d",&v); n = max(n,max(u,v)); add(u,v); add(v,u); scanf("%d",&u); }while(u); for(i = 1; i <= n; ++ i) if(!dfn[i])tarjan(-1,i); for(i = 1; i <= n; ++ i) if(vis[i]){ tot = 0; memset(gone,0,sizeof(gone)); gone[i] = 1; for(j = head[i]; j != -1; j = edge[j].next) if(!gone[edge[j].v]){ tot++; dfs(-1,edge[j].v); } if(tot>1){printf(" SPF node %d leaves %d subnets\n",i,tot); flag = 1;} } if(!flag)puts(" No SPF nodes"); return 1; } int main() { while(1){if(cas)puts("");if(sovle()==0)break;} return 0; }