题目描述
SGOI 旅游局在 SG-III 星团开设了旅游业务,每天有数以万计的地球人来这里观光,包括联合国秘书长,各国总统和 SGOI 总局局长等。旅游线路四通八达,每天都有众多的载客太空飞船在星团的星球之间来往穿梭,他们保证了任意两个星球之间总是可以通过航道到达。
但是,最近由于财政出现了困难,一些太空飞船也过于古老,又没有足够的资金购买新产品,所有只好取消一些航道。如果某一条航道的删除使得一些星球不能到达,那么这条航道是不能删除的,称之为「主要航道」。
SGOI 旅游局局长希望知道主要航道的数目,但是航道较多,他不能手工计算,于是,他委托你写一个程序,计算主要航道数目。
输入格式
输入文件包含若干组数据。
每组数据的首行有两个数 m,n 。星球的编号从 1 到 m 。
以下 n 行每行用两个整数 a,b 描述一条航道的信息,表示从星球 a 到星球 b 是有航道的。数据由 SGOI 旅游局提供,你无需担心数据有错。
输入文件以一行0 0
为结束。
输出格式
输出文件共有 C 行,第 i 行仅有一个数,表示第 i 组输入数据的主要行道数目。
样例
样例输入
2 1
1 2
0 0
样例输出
1
数据范围与提示
1<=m,n<=3e4,1<=a,b<=m
_________________________________
求图中桥的数量
_________________________________
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=3e4+10; 4 struct edge 5 { 6 int u,v,nxt,nok; 7 }e[maxn<<1]; 8 int head[maxn],js; 9 void addage(int u,int v) 10 { 11 e[++js].u=u;e[js].v=v; 12 e[js].nxt=head[u];head[u]=js; 13 } 14 int n,m; 15 int dfn[maxn],low[maxn],cnt; 16 inline int dz(int x) 17 { 18 return x&1?x+1:x-1; 19 } 20 int ans; 21 void tarjan(int u) 22 { 23 low[u]=dfn[u]=++cnt; 24 for(int i=head[u];i;i=e[i].nxt) 25 if(!e[i].nok) 26 { 27 int v=e[i].v; 28 e[dz(i)].nok=1; 29 if(!dfn[v]) 30 { 31 tarjan(v); 32 low[u]=min(low[u],low[v]); 33 if(low[v]>dfn[u])ans++; 34 } 35 else low[u]=min(low[u],dfn[v]); 36 } 37 } 38 void init() 39 { 40 js=0; 41 memset(head,0,sizeof head); 42 ans=0; 43 memset(low,0,sizeof low); 44 memset(dfn,0,sizeof dfn); 45 memset(e,0,sizeof e); 46 cnt=0; 47 } 48 int main() 49 { 50 while(scanf("%d%d",&n,&m),n|m) 51 { 52 init(); 53 for(int u,v,i=0;i<m;++i) 54 { 55 scanf("%d%d",&u,&v); 56 addage(u,v); 57 addage(v,u); 58 } 59 tarjan(1); 60 printf("%d ",ans); 61 } 62 return 0; 63 }