dfs
不是根节点:如果边数大于等于2,则删除与父节点的边。并且是一条环,那么每个点的度数是2,则还要删除num(每个节点儿子数)-2,只留两个儿子。当然删除边的儿子也要连到环上,又是一个num(每个节点儿子数)-2次操作。最后不同分支之间还要连一条边。所以复杂度为:2*(num-1)。
根:不用删父亲边和连分支边。2*(num-2)
注意本题要手动扩栈
1 #pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<queue> 7 #include<stack> 8 #include<cmath> 9 #include<algorithm> 10 #include<vector> 11 #include<malloc.h> 12 using namespace std; 13 #define clc(a,b) memset(a,b,sizeof(a)) 14 #define inf 0x3f3f3f3f 15 const int N=10010; 16 #define LL long long 17 const double eps = 1e-5; 18 const double pi = acos(-1); 19 // inline int r(){ 20 // int x=0,f=1;char ch=getchar(); 21 // while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘) f=-1;ch=getchar();} 22 // while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 23 // return x*f; 24 // } 25 vector<int>g[1000010]; 26 int ans; 27 int vis[1000010]; 28 int dfs(int u){ 29 int num=0; 30 vis[u]=true; 31 for(int i=0;i<g[u].size();i++){ 32 int v=g[u][i]; 33 if(vis[v]==0){ 34 num+=dfs(v); 35 } 36 } 37 if(num>=2){ 38 if(u==1){ 39 ans+=2*(num-2); 40 } 41 else 42 ans+=2*(num-1); 43 return 0; 44 } 45 else 46 return 1; 47 } 48 int main(){ 49 // freopen("in.txt","r",stdin); 50 int T; 51 scanf("%d",&T); 52 while(T--){ 53 ans=0; 54 int n; 55 clc(vis,0); 56 scanf("%d",&n); 57 for(int i=0;i<=n;i++) g[i].clear(); 58 for(int i=0;i<n-1;i++){ 59 int u,v; 60 scanf("%d%d",&u,&v); 61 g[u].push_back(v); 62 g[v].push_back(u); 63 } 64 int num=dfs(1); 65 printf("%d\n",++ans); 66 } 67 return 0; 68 }
时间: 2024-10-13 11:29:02