poj 1523 割点
题意:问每个割点分别和几个连通分量相连
分析:每确定一次u是割点,rudu[u]+1,若u不是根又是割点,rudu[u]再+1
#define M 1011 struct Node{ int v,next; }edge[M<<4]; int len; int old[M],n; int nb; int tim[M],t; int sta[M],top; int low[M],hash[M];//原结点向新结点映射 int rudu[M]; int bs[M],be[M],bb;//桥 int Case; void add(int &kind,int v){ edge[len].next=kind; edge[len].v=v; kind=len++; } int rtIsPoint;//根是否是割点 void dfs(int u, int father) { tim[u] = low[u] = t ++; sta[++top] = u; bool isu=false; //cout<<"AAAAAAAAAA"<<endl; for(int i = old[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v; if(v == father) continue; //cout<<"v="<<v<<endl; if(tim[v] == -1) {//父子边 //cout<<u<<' '<<v<<' '<<father<<endl; dfs(v, u); checkmin(low[u],low[v]); if(father == -1 && i == old[u])//判根是否割点 for(int j = edge[i].next; j!=-1; j=edge[j].next) if(tim[ edge[j].v ] == -1){rtIsPoint = 1; break;} //cout<<u<<' '<<v<<' '<<tim[u]<<' '<<low[v]<<endl; if((tim[u] <= low[v] && father != -1) || //u是割点 (rtIsPoint == 1 && father == -1)){ isu=true; //while(u != sta[top]) hash[ sta[top--] ]=nb; //nb++; //bs[bb]=u; //割点到相连的分量的一条边 //be[bb++]=v; rudu[u]++; } } else checkmin(low[u],tim[v]);//返祖边 } if(isu && father != -1) rudu[u]++; } int cnt; void Tarjan() { //cout<<"BBBBBBB"<<endl; FOR(i,1,n+1) { rtIsPoint=0; if(tim[i] == -1) dfs(i , -1); } cout<<"Network #"<<++Case<<endl; FF(i,n+1) if(rudu[i]){ cout<<" SPF node "<<i<<" leaves "<<rudu[i]<<" subnets"<<endl; cnt++; } if(!cnt)cout<<" No SPF nodes"<<endl; cout<<endl; } void init(){ //cout<<n<<endl; memset(tim,-1,sizeof(int)*(n+1)); //memset(hash,-1,sizeof(int)*(n+1)); memset(rudu,0,sizeof(int)*(n+1)); //cout<<tim[5]<<endl; len = t = top = nb = cnt = bb = rtIsPoint = 0; } void build(){ int a,b; while(cin>>a,a){ cin>>b; add(old[a],b); add(old[b],a); n++; } } int main() { int a,b; while(cin>>a,a){ cin>>b; memset(old,-1,sizeof(old)); add(old[a],b); add(old[b],a); n++; build(); init(); Tarjan(); } }