//自己写的第一发tarjan
解:先进行双连通分解并缩点,分解后一定是一颗树,设叶节点个数为n那么答案就是(n+1)/2
关于双连通分量求解:在跑tarjan时判断每个点连向父节点的边是否是桥,如果是桥的话,该点的后代
中,未被染色的节点一点构成一个双连通分量,那么将其染色。
染色完成后依次检查每一条边的两端是
否为两种不同的颜色,如果是,所对应的颜色的度+1,最后看多少个度为1的节点就知道有多少叶子节点
也就能得到答案了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<stack> 11 #include<string> 12 13 using namespace std; 14 15 const int MAXN=100007; 16 const int MAXM=100007; 17 18 vector<int> G[MAXN]; 19 int n,m,top,cnt1,cnt2; 20 bool vis[MAXN]; 21 int color[MAXN],dfn[MAXN],low[MAXN]; 22 int stk[MAXN]; 23 int degree[MAXN]; 24 25 void tarjan(int now,int fa){ 26 cnt1++; 27 dfn[now]=low[now]=cnt1; 28 vis[now]=1; 29 stk[top++]=now; 30 int sz=G[now].size(); 31 for (int i=0;i<sz;i++){ 32 if (G[now][i]==fa) continue; 33 if (!vis[G[now][i]]){ 34 tarjan(G[now][i],now); 35 low[now]=min(low[now],low[G[now][i]]); 36 if (low[G[now][i]]>dfn[now]){ 37 cnt2++; 38 while (top>0){ 39 color[stk[--top]]=cnt2; 40 if (stk[top]==G[now][i]) break; 41 } 42 } 43 } 44 else{ 45 low[now]=min(low[now],dfn[G[now][i]]); 46 } 47 } 48 } 49 50 int main(){ 51 while (scanf("%d%d",&n,&m)==2){ 52 cnt1=cnt2=top=0; 53 memset(vis,0,sizeof(vis)); 54 memset(degree,0,sizeof(degree)); 55 memset(color,0,sizeof(color)); 56 memset(dfn,0,sizeof(dfn)); 57 memset(low,0,sizeof(low)); 58 memset(stk,0,sizeof(stk)); 59 for (int i=1;i<=n;i++){ 60 G[i].clear(); 61 } 62 for (int i=0;i<m;i++){ 63 int x,y; 64 scanf("%d%d",&x,&y); 65 G[x].push_back(y); 66 G[y].push_back(x); 67 } 68 for (int i=1;i<=n;i++){ 69 if (dfn[i]==0) tarjan(i,-1); 70 } 71 if (cnt2==1){ 72 printf("0 "); 73 continue; 74 } 75 for (int i=1;i<=n;i++){ 76 int sz=G[i].size(); 77 for (int j=0;j<sz;j++){ 78 if (color[i]!=color[G[i][j]]){ 79 degree[color[i]]++; 80 } 81 } 82 } 83 int ans=0; 84 for (int i=1;i<=cnt2;i++){ 85 if (degree[i]==0) ans+=2; 86 if (degree[i]==1) ans+=1; 87 } 88 printf("%d ",(ans+1)/2); 89 } 90 return 0; 91 } 92 /* 93 7 7 94 1 2 95 2 3 96 3 4 97 2 5 98 4 5 99 5 6 100 5 7 101 102 3 3 103 1 2 104 2 3 105 1 3 106 107 108 7 5 109 1 2 110 2 3 111 4 5 112 5 6 113 5 7 114 */