Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7990 | Accepted: 3768 |
Description
Input
Output
Sample Input
5Sample Output
1Hint
You need to determine the end of one line.In order to make it's easy to determine,there are no extra blank before the end of each line
/*********************************************************************** * problem: POJ 1144-network * algorithm: tarjan * 割点判断条件:1:如果点v是DFS序列的根节点,则如果v有一个以上的孩子, * 则v是一个割点。 * 2.如果v不是DFS序列根节点,并且点v的任意后继u能追溯到最早的祖先节点 * low[u]>=dfn[v],则v是一个割点。 * 分类:ACM成长之路 * 难度:容易题 * author:sgx * date:2013/09/11 * PS:水题还WA两发,无语了。。。原来是求割点的时候忘了判断u==father只写else不行 * 必须写成else(u==father),晕菜~· **************************************************************************/ #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=100+5; struct Edge { int to; int next; }edge[maxn*20]; int head[maxn]; int dfn[maxn],low[maxn]; bool iscut[maxn];//判断是否为割点; int Bcnt,n;//记录连通分量个数; int cnt,index,son_num; int res; inline int max(int a,int b) { return a>b?a:b; } inline int min(int a,int b) { return a<b?a:b; } inline void addedge(int u,int v) { edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++; } inline void makemap(int from,int to) { addedge(from,to); addedge(to,from); } inline void tarjan(int u,int father) { dfn[u]=low[u]=++index; for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].to; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[v],low[u]); if(low[v]>=dfn[u]&&u!=father)//判断是否为割点; { iscut[u]=true; } else if(u==father)//这儿WA两次; son_num++; } else low[u]=min(low[u],dfn[v]); } } void solve() { res=son_num=index=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(iscut,false,sizeof(iscut)); tarjan(1,1); if(son_num>1) res++; for(int i=2;i<=n;i++) { if(iscut[i]) res++; } printf("%d\n",res); } int main() { char ch; while(scanf("%d",&n)&&n) { cnt=0; memset(head,-1,sizeof(head)); int u,v; while(scanf("%d",&u)&&u) { while((ch=getchar())!='\n') { scanf("%d",&v); makemap(u,v); } } solve(); } return 0; }