由于内存的限制。所以尽量要少开数组。一开始用了数组记录每个点的度数和每个点的儿子数,还有vis记录这个点是否处理过。然后超内存了。
实际上儿子数没有必要存下来,只是每次遍历自身的时候会用到,然后是否用过可以是每次dfs的返回值。
void dfs(int u,int f) { for(int i=head[u];~i;i=edge[i].next) { int v=edge[i].v; if(v==f)continue; fa[v]=u; dfs(v,u); if(son[v]>=2) { num+=degree[v]-2;//删除v的n-1个儿子以及<u,v> vis[v]=1;//删除v节点 degree[fa[v]]--;//让其父节点的度-1 } if(!vis[v]) son[u]+=1;//统计儿子个数 } }
超内存的写法。
#include <cstdio> #include <cstring> #include <iostream> #define Max 1000001 #define MAXN 1001009 #define MOD 1000000007 #define rin freopen("in.txt","r",stdin) #define rout freopen("1.out","w",stdout) #define Del(a,b) memset(a,b,sizeof(a)) typedef long long LL; using namespace std; const int N = 1000005; int T; struct Node { int next; int to; } e[N*2]; int tot, ans; int head[N]; void Init(int n) { Del(head, -1); ans=0; tot = 0; } void addedge(int from, int to) { e[tot].to = to; e[tot].next = head[from]; head[from] = tot++; } int dfs(int u, int father) { int son=0; for (int i = head[u]; i != -1; i = e[i].next) { int v=e[i].to; if(v==father) continue; son+=dfs(v,u); } if(son>=2){ ans+=son-1; if(u==1) ans--; return 0; } else return 1; } int main() { rin; int n,T; while (cin >> T) { while (T--) { scanf("%d", &n); Init(n); for (int i = 1; i < n; i++) { int x, y; scanf("%d%d", &x, &y); addedge(y, x); addedge(x, y); } dfs(1,-1); printf("%d\n",ans*2+1); } } return 0; }
时间: 2024-11-09 12:59:42