标签:
Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 2161 Accepted Submission(s): 508
/* 每个节点如果有两个或两个以上结点,就将它先于父节点断开,然后在与子节点断开,全部断开之后,和子节点自称一条直链,最后将所有的子链连城一条 直线一个结点有sum个子结点,断开是需要sum-2次操作,连接时需要sum-2次操作,这样一个结点就会进行2*(sum-2)次操作,这时加上断开父节点,一共 进行了2*(sum-2)+1次操作,构成直链之后还需要和父节点连接,这样就一共是2*(sum-1)次操作,如果这个结点是刚开始的结点,那么就不用考虑父节 点,这样操操作就是2*(sum-2)次 */ #include <stdio.h> #include <algorithm> #include <iostream> #include <string.h> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #define N 1000009 using namespace std; int t,n; vector<int > edge[N]; int ans=0; bool dfs(int u,int p)//返回你搜到的是不是u的子树 { //cout<<"ans="<<ans<<endl; int sum=0; for(int i=0;i<edge[u].size();i++) { int v=edge[u][i];//下一步 if(v==p) continue;//下一步走过了,就不要走了 sum+=dfs(v,u); //visit[v]=true; //cout<<sum<<endl; } if(sum>=2) { if(u==1) ans+=2*(sum-2); else ans+=2*(sum-1); return false; } return true; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d",&t); while(t--) { scanf("%d",&n); ans=0; int from,to; for(int i=0;i<=n;i++) edge[i].clear(); for(int i=0;i<n-1;i++) { scanf("%d%d",&from,&to); //cout<<from<<" "<<to<<endl; edge[from].push_back(to); edge[to].push_back(from); }//建树 dfs(1,-1); printf("%d\n",ans+1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/wuwangchuxin0924/p/5795902.html