BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / acm-icpc / #91474同步于 2016/10/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
ACM_ICPC机器人发帖

[问题]请教杭电5927题,为什么一直在T?

lhy963
2016/10/21镜像同步4 回复
传送门 http://acm.hdu.edu.cn/showproblem.php?pid=5927 解释一下题意就是这样的: 给你一棵树,1为根,然后选择一部分点叫做“重要点”;定义“重要点集合”是这样的点: (1)重要点属于重要点集; (2)两个重要点的最近公共祖先属于重要点集; 然后给你q次询问,每次询问输入一些“非重要点”,然后输出重要点集合有几个点? ``` #include <bits/stdc++.h> using namespace std; typedef long long ll; int T; int n,q,u,v,mi; vector<int> g[100005]; int fa[100005]; int dp[100005]; int dp2[100005]; int m[100005]; int deep[100005]; int imp[100005]; int ans; void dfs(int u,int par,int d) { deep[u]=d; if(!fa[u]) fa[u]=par; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(!fa[v]) { dfs(v,u,d+1); dp[u]++; } } } bool cmp(int x,int y) { return deep[y]<deep[x]; } void solve() { sort(m,m+mi,cmp); for(int i=0;i<mi;i++) { int u=m[i]; if(dp2[u]==0)//u点非重要 且u点的孩子没有重要点 dp2[fa[u]]--; } for(int i=0;i<mi;i++) { int u=m[i]; if(dp2[u]>=2) ans++; } // for(int i=1;i<=n;i++) { // printf("dp2[%d] = %d\n", i,dp2[i]); // } } int main() { scanf("%d",&T); for(int t=1;t<=T;t++) { scanf("%d %d",&n,&q); memset(fa,0,sizeof(fa)); memset(dp,0,sizeof(dp)); memset(deep,0,sizeof(deep)); memset(g,0,sizeof(g)); for(int i=0;i<n-1;i++) { scanf("%d %d",&u,&v); g[u].push_back(v); g[v].push_back(u); } dfs(1,-1,0);//确定父子关系和深度 // for(int i=1;i<=n;i++) { // printf("fa[%d] = %d,dp[%d] = %d\n", i,fa[i],i,dp[i]); // } printf("Case #%d:\n",t); while(q--) { memset(m,0,sizeof(m)); memset(imp,0,sizeof(imp));//都是非重要的 scanf("%d",&mi); for(int i=0;i<mi;i++) { scanf("%d",&m[i]); //imp[m[i]]=1; } for(int i=0;i<mi;i++) dp2[m[i]]=dp[m[i]]; ans=n-mi; solve(); printf("%d\n", ans); } } } ``` 这段代码提交一直T,网上搜到的题解的AC代码如下: ``` #include <bits/stdc++.h> using namespace std; const int N=1e5+5; int L[N]; int cnt[N]; int tail; vector<int> g[N]; int par[N]; void dfs(int u, int f){ L[u]=++tail; par[u]=f; for(auto v: g[u]){ if(v!=f){ ++cnt[u]; dfs(v, u); } } } bool cmp(int x, int y){ return L[x]>L[y]; } vector<int> a; // unimportant nodes int _cnt[N]; // bool flag[N]; int main(){ int T, cas{}; for(cin>>T; T--; ){ int n, q; cin>>n>>q; for(int i=1; i<=n; i++){ g[i].clear(); cnt[i]=0; // error-prone } for(int i=1; i<n; i++){ int u, v; scanf("%d%d", &u, &v); g[u].push_back(v); g[v].push_back(u); } tail=0; dfs(1, 0); printf("Case #%d:\n", ++cas); for(; q--; ){ int m; cin>>m; a.clear(); for(; m--; ){ int x; scanf("%d", &x); a.push_back(x); // flag[x]=true; } sort(a.begin(), a.end(), cmp); for(auto x: a){ _cnt[x]=cnt[x]; } for(auto x: a){ if(_cnt[x]==0){ --_cnt[par[x]]; } } int res=0; for(auto x: a){ res+=_cnt[x]>=2; // _cnt[x]=cnt[x]; } res += n-a.size(); printf("%d\n", res); } } return 0; } ``` 看了一下午也没看出来我跟他写的有何区别,主要区别就是他没有我用这么多全局变量。但我记得全局区速度更快的呀,为什么他能ac我就T。 跪求大神指教~~
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
hiyot机器人#1 · 2016/10/21
memset(g,0,sizeof(g)); 这句话可能T
hiyot机器人#2 · 2016/10/21
while(q--) { memset(m,0,sizeof(m)); } 这里更可能T
lhy963机器人#3 · 2016/10/21
的确,注释掉这句之后a了 【 在 hiyot 的大作中提到: 】 : while(q--) { : memset(m,0,sizeof(m)); : } : ...................
lhy963机器人#4 · 2016/10/21
那多测试点下,清空一个图的邻接表怎么搞? 【 在 hiyot 的大作中提到: 】 : memset(g,0,sizeof(g)); 这句话可能T