PTA_L2题解集
前言:L2部分我感觉更侧重于算法基础或者思维,L1部分偏语法。L2一些数据结构课本题我都不写了,没意思。
L2-001 紧急救援
题解:因为没有负边权,所以我使用的是最优化的优先队列dijkstra算法。设num[i]表示到达i点最短路的路径数量,sum[i]表示到达i点最短路的时候的最大权值和。当d[v]>d[u]+edge[i].w时,更新d[v]值,同时num[v]=num[u] . sum[v]=sum[u]+a[v]。如果d[v]=d[u]+edge[i].w时,需要更新的是num[v]的数量,即num[v]+=num[u],同时可以更新sum的情况,if(sum[v]<sum[u]+a[v]) sum[v]=sum[u]+a[v];具体看代码
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define white 0 #define grey 1 #define black 2 #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=3e5+5; int tot,head[maxn]; struct E{ int to,next,w; }edge[maxn<<1]; void add(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } int n,m,S,T; int a[maxn],d[maxn],color[maxn],pre[maxn]; int num[maxn],sum[maxn]; priority_queue<pair<int,int> >q; void dijkstra(int s){ for(int i=1;i<=n;i++) color[i]=white,d[i]=INF,pre[i]=s; q.push({0,s});d[s]=0;color[s]=grey; num[s]=1;sum[s]=a[s];pre[s]=0; while(!q.empty()){ pair<int,int> f=q.top();q.pop(); int u=f.second; color[u]=black; if(d[u]<(-1)*f.first) continue; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(color[v]==black) continue; if(d[v]>d[u]+edge[i].w){ d[v]=d[u]+edge[i].w; pre[v]=u; num[v]=num[u]; sum[v]=sum[u]+a[v]; color[v]=grey; q.push({(-1)*d[v],v}); } else if(d[v]==d[u]+edge[i].w){ num[v]+=num[u]; if(sum[v]<sum[u]+a[v]){ sum[v]=sum[u]+a[v]; pre[v]=u; } } } } } stack<int> s; void get_path(int t){ while(t){ s.push(t-1); t=pre[t]; } } int main(){ scanf("%d%d%d%d",&n,&m,&S,&T);mem(head,-1); ++S;++T; rep(i,1,n) scanf("%d",&a[i]); rep(i,1,m){ int u,v,w;scanf("%d%d%d",&u,&v,&w); ++u;++v; add(u,v,w);add(v,u,w); } dijkstra(S); cout<<num[T]<<" "<<sum[T]<<endl; get_path(T); while(!s.empty()){ int cur=s.top();s.pop(); if(s.size()) cout<<cur<<" "; else cout<<cur; } }
L2-002 链表去重
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; struct Node{ int address,key,next,num; }node[maxn]; bool vis[maxn]; bool cmp(Node a,Node b){ return a.num<b.num; } int main(){ int head,n;scanf("%d%d",&head,&n); for(int i=0;i<maxn;i++) node[i].num=INF; for(int i=0;i<n;i++){ int a;scanf("%d",&a); scanf("%d%d",&node[a].key,&node[a].next); node[a].address=a; } int k1=0,k2=0; for(int i=head;i!=-1;i=node[i].next){ if(!vis[abs(node[i].key)]){ vis[abs(node[i].key)]=true; node[i].num=k1++; }else{ node[i].num=maxn+k2; k2++; } } sort(node,node+maxn,cmp); int k=k1+k2; for(int i=0;i<k;i++){ if(i!=k1-1&&i!=k-1){ printf("%05d %d %05d\n",node[i].address,node[i].key,node[i+1].address); }else{ printf("%05d %d -1\n",node[i].address,node[i].key); } } }
L2-003 月饼
坑点:注意正数与正整数的区别,用double输入比较安全
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; double w[maxn],p[maxn];double s[maxn]; struct Node{ double s,t; }node[maxn]; bool cmp(Node a,Node b){ return a.s>b.s; } int main(){ int n,weight;scanf("%d%d",&n,&weight); rep(i,1,n) scanf("%lf",&w[i]); rep(i,1,n) scanf("%lf",&p[i]); rep(i,1,n){ node[i].s=1.00*p[i]/w[i]; node[i].t=w[i]; } sort(node+1,node+n+1,cmp); double ans=0; rep(i,1,n){ if(weight>=node[i].t){ weight-=node[i].t; ans+=node[i].t*node[i].s; }else{ ans+=weight*node[i].s; weight=0; } if(!weight) break; } printf("%.2lf\n",ans); }
L2-005 集合相似度
坑点:能尽量优化减少对于set的使用和遍历次数
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; set<int> s[maxn]; int main(){ int n;scanf("%d",&n); rep(i,1,n){ int t;scanf("%d",&t); while(t--){ int x;scanf("%d",&x); s[i].insert(x); } } int k;scanf("%d",&k); while(k--){ int a,b;scanf("%d%d",&a,&b); int cnt=0; for(auto it:s[b]){ if(s[a].count(it)) ++cnt; } double ans=1.00*cnt/(s[a].size()+s[b].size()-cnt); printf("%.2lf%\n",ans*100); } }
L2-007家庭房产
题解:大模拟+bfs建边跑连通块维护连通块信息
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int tot,head[maxn]; struct E{ int to,next; }edge[maxn<<2]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int n,a[maxn],num[maxn],s[maxn]; bool vis[maxn]; struct node{ vector<int> vec; int num,s; int minn,t; double averT,averSIZ; }p[maxn]; void bfs(int x,int id){ queue<int> q;q.push(x); while(!q.empty()){ int now=q.front();q.pop(); p[id].vec.push_back(now); p[id].num+=num[now]; p[id].s+=s[now]; for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to; if(vis[v]) continue; vis[v]=true; q.push(v); } } } bool cmp(node a,node b){ if(a.averSIZ!=b.averSIZ) return a.averSIZ>b.averSIZ; else return a.minn<b.minn; } int main(){ scanf("%d",&n);mem(head,-1); rep(i,1,n){ int id,L,R;scanf("%d%d%d",&id,&L,&R); a[id]=1; if(L!=-1) a[L]=1,add(id,L),add(L,id); if(R!=-1) a[R]=1,add(id,R),add(R,id); int k;scanf("%d",&k); while(k--){ int x;scanf("%d",&x); a[x]=1; add(id,x);add(x,id); } scanf("%d%d",&num[id],&s[id]); } int cnt=0; for(int i=0;i<=9999;i++){ if(a[i]&&!vis[i]){ vis[i]=true; bfs(i,++cnt); p[cnt].minn=i; } } for(int i=1;i<=cnt;i++){ p[i].minn=p[i].vec[0]; p[i].t=p[i].vec.size(); p[i].averT=1.000*p[i].num/p[i].t; p[i].averSIZ=1.000*p[i].s/p[i].t; } sort(p+1,p+cnt+1,cmp); cout<<cnt<<endl; rep(i,1,cnt){ printf("%04d %d %.3lf %.3lf\n",p[i].minn,p[i].t,p[i].averT,p[i].averSIZ); } }
L2-008 最长对称子串
题解:马拉车算法模板裸题,输入用getline输入
#include <bits/stdc++.h> using namespace std; const int maxn=1e7+5; string s; char str[maxn<<1]; int p[maxn<<1]; int init(){ int len=s.length(); str[0]='@',str[1]='#'; int j=2; for(int i=0;i<len;i++) str[j++]=s[i],str[j++]='#'; str[j]='\0'; return j; } int manacher(){ int ans=-1,len=init(),mx=0,id=0; for (int i=1;i<len;i++) { if(i<mx) p[i]=min(p[id*2-i],mx-i); else p[i]=1; while(str[i+p[i]]==str[i-p[i]]) p[i]++; if(p[i]+i>mx) mx=p[i]+i,id=i; ans=max(ans,p[i]-1); } return ans; } int main(){ getline(cin,s); cout<<manacher(); return 0; }
L2-009 抢红包
题解:模拟
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; struct node{ int id,ct;double w; }q[maxn]; int p[maxn],cnt[maxn]; bool cmp(node a,node b){ if(a.w!=b.w) return a.w>b.w; else{ if(a.ct!=b.ct) return a.ct>b.ct; else{ if(a.id!=b.id) return a.id<b.id; } } } int main(){ int n;scanf("%d",&n); rep(i,1,n){ int k;scanf("%d",&k); while(k--){ int a,b;scanf("%d%d",&a,&b); p[a]+=b;p[i]-=b; cnt[a]+=1; } } rep(i,1,n){ q[i].ct=cnt[i],q[i].id=i;q[i].w=p[i];q[i].w/=100; } sort(q+1,q+n+1,cmp); rep(i,1,n){ printf("%d %.2lf\n",q[i].id,q[i].w); } }
L2-010 排座位
题解:有点绕,理清楚逻辑关系用Floyd就行
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e2+5; int d[maxn][maxn],r[maxn][maxn],z[maxn][maxn],fa[maxn]; int find(int x){ while(x!=fa[x]) x=fa[x]=fa[fa[x]]; return x; } int n,m,q; int x[maxn][maxn]; int main(){ scanf("%d%d%d",&n,&m,&q); rep(i,1,n) fa[i]=i; mem(d,INF); rep(i,1,m){ int u,v,w;scanf("%d%d%d",&u,&v,&w); if(w==-1) d[u][v]=INF,d[v][u]=INF,x[u][v]=x[v][u]=1; else d[u][v]=0,d[v][u]=0,z[u][v]=z[v][u]=1; r[u][v]=r[v][u]=1; int eu=find(u),ev=find(v); if(eu!=ev){ fa[ev]=eu; } } rep(i,1,n) d[i][i]=0; for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } } } while(q--){ int u,v;scanf("%d%d",&u,&v); if(find(u)==find(v)){ if(z[u][v]) puts("No problem"); else{ if(!r[u][v]) {puts("OK");continue;} if(x[u][v]){ if(d[u][v]==0) puts("OK but..."); else puts("No way"); } } }else{ puts("OK"); } } }
L2-013 红色警报
题解:因为n=500,所以可以暴力做法,每次执行2次dsu 。 或者反向加点
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=5000+5; int tot,head[505]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int n,m,vis[505],p[505]; void dfs(int x){ vis[x]=1; for(int i=head[x];i!=-1;i=edge[i].next){ int v=edge[i].to; if(vis[v]||p[v]) continue; vis[v]=1; dfs(v); } } int main(){ scanf("%d%d",&n,&m);mem(head,-1); rep(i,1,m){ int u,v;scanf("%d%d",&u,&v); add(u,v);add(v,u); } int q;scanf("%d",&q);int lol=0; while(q--){ int x;scanf("%d",&x);++lol; for(int i=0;i<n;i++) vis[i]=0; int cnt=0; for(int i=0;i<n;i++){ if(!vis[i]&&!p[i]){ ++cnt; dfs(i); } } p[x]=1; int ct=0; for(int i=0;i<n;i++) vis[i]=0; for(int i=0;i<n;i++){ if(!vis[i]&&!p[i]){ ++ct; dfs(i); } } if(ct-cnt>0) printf("Red Alert: City %d is lost!\n",x); else printf("City %d is lost.\n",x); if(lol==n) puts("Game Over."); } }
L2-014 列车调度
题解:和Hdoj的导弹拦截一样,推出规律就是LIS,但是要一个O(nlogn)的做法,否则会TLE
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int a[maxn],g[maxn],dp[maxn]; int main(){ int n;scanf("%d",&n); rep(i,1,n) scanf("%d",&a[i]); mem(g,INF);int ans=-1; for(int i=1;i<=n;i++){ int pos=lower_bound(g+1,g+n+1,a[i])-g; dp[i]=pos+1; if(ans<dp[i]) ans=dp[i]; g[pos]=a[i]; } cout<<ans-1<<endl; }
L2-015 互评成绩
题解:模拟
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e4+5; int n,m,k; int a[maxn][12]; double ans[maxn]; int main(){ scanf("%d%d%d",&n,&m,&k); rep(i,1,n){ rep(j,1,m){ scanf("%d",&a[i][j]); } sort(a[i]+1,a[i]+1+m); ans[i]=0; rep(j,2,m-1) ans[i]+=a[i][j]; ans[i]=1.000*ans[i]/(m-2); } sort(ans+1,ans+n+1); rep(i,n-k+1,n){ if(i!=n) printf("%.3lf ",ans[i]); else printf("%.3lf\n",ans[i]); } }
L2-019 悄悄关注
题解:模拟
#include<bits/stdc++.h> #define endl '\n' #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=1e4+5; string s[maxn];int cnt[maxn]; int main(){ int n;cin>>n; map<string,int> mp; rep(i,1,n){ string ss;cin>>ss; mp[ss]=1; } int m;cin>>m; double sum=0; rep(i,1,m){ cin>>s[i]>>cnt[i]; sum+=cnt[i]; } vector<string> vec; sum=1.000*sum/m; rep(i,1,m){ if(!mp[s[i]]){ if(cnt[i]>sum) vec.push_back(s[i]); } } if(!vec.size()) puts("Bing Mei You"); else{ sort(vec.begin(),vec.end()); for(auto it:vec){ cout<<it<<endl; } } }
L2-020 功夫传人
坑点:祖师爷自己就是得道者,没有弟子,所以需要自己放大自己
#include<bits/stdc++.h> #define endl '\n' #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=1e5+5; int head[maxn],tot; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int n;double z[maxn],r; double b[maxn];int vis[maxn]; double sum; void dfs(int x,int fa){ for(int i=head[x];i!=-1;i=edge[i].next){ int v=edge[i].to; z[v]=z[x]*1.00*(100-r)/100*b[v]; dfs(v,x); } } int main(){ cin>>n>>z[0]>>r; memset(head,-1,sizeof(head));sum=0; for(int i=0;i<n;i++) b[i]=1.00; rep(i,0,n-1){ int t;cin>>t; if(!t){ cin>>b[i];vis[i]=1; }else{ rep(j,1,t){ int x;cin>>x; add(i,x); } } } z[0]*=b[0]; dfs(0,-1); rep(i,0,n-1){ if(vis[i]) sum+=z[i]; } long long x=floor(sum); cout<<x<<endl; }
L2-023 图着色问题
坑点:边的数量2.5e5,以及颜色数一定要等于k
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=3e5+5; int tot,head[505]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int n,m,k,col[505]; int main(){ cin>>n>>m>>k;mem(head,-1); rep(i,1,m){ int u,v;cin>>u>>v; add(u,v);add(v,u); } int t;cin>>t; while(t--){ set<int> s; rep(i,1,n){ cin>>col[i]; s.insert(col[i]); } if(s.size()!=k){puts("No");continue;} rep(i,1,n){ for(int j=head[i];j!=-1;j=edge[j].next){ int v=edge[j].to; if(col[v]==col[i]){ puts("No"); goto end; } } } puts("Yes"); end:; } }
L2-024 部落
题解:图论建边,bfs标记连通块
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e7+5; int tot,head[10005]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int vis[10005]; void bfs(int x,int id){ queue<int> q;q.push(x); while(!q.empty()){ int now=q.front();vis[now]=id;q.pop(); for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to; if(vis[v]) continue; vis[v]=id; q.push(v); } } } int main(){ int T;cin>>T;mem(head,-1);set<int> s; while(T--){ int k;cin>>k; vector<int> vec; rep(i,1,k){ int x;cin>>x; vec.pb(x);s.insert(x); } for(int i=1;i<vec.size();i++){ add(vec[i-1],vec[i]);add(vec[i],vec[i-1]); } } int cnt=0; for(int i=1;i<=s.size();i++){ if(!vis[i]){ bfs(i,++cnt); } } int q;cin>>q; vector<char> vec; while(q--){ int u,v;cin>>u>>v; if(vis[u]==vis[v]) vec.pb('Y'); else vec.pb('N'); } cout<<s.size()<<" "<<cnt<<endl; for(auto it:vec){ cout<<it<<endl; } }
L2-025 分而治之
题解:模拟,图论
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int tot,head[maxn]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int n,m,vis[maxn]; int main(){ cin>>n>>m;mem(head,-1); rep(i,1,m){ int u,v;cin>>u>>v; add(u,v);add(v,u); } int T;cin>>T; queue<int> q; while(T--){ int k;cin>>k; rep(i,1,k){ int x;cin>>x; q.push(x);vis[x]=1; } rep(i,1,n){ if(vis[i]) continue; for(int j=head[i];j!=-1;j=edge[j].next){ int v=edge[j].to; if(!vis[v]){ puts("NO"); goto end; } } } puts("YES"); end:; while(!q.empty()){ int now=q.front();q.pop(); vis[now]=0; } } }
L2-026小字辈
题解:dfs
#include<bits/stdc++.h> #pragma GCC optimize(2) #define ll long long #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int tot,head[maxn]; struct E{ int to,next; }edge[maxn<<1]; void add(int u,int v){ edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } int id[maxn],maxx; void dfs(int x,int level){ id[x]=level;maxx=max(maxx,level); for(int i=head[x];i!=-1;i=edge[i].next){ int v=edge[i].to; dfs(v,level+1); } } int main(){ int n,rt;maxx=-INF;cin>>n;mem(head,-1); rep(i,1,n){ int x;cin>>x; if(x!=-1) add(x,i); else rt=i; } dfs(rt,1); cout<<maxx<<endl; vector<int> vec; rep(i,1,n){ if(id[i]==maxx) vec.pb(i); } for(int i=0;i<vec.size();i++){ if(i==vec.size()-1) cout<<vec[i]<<endl; else cout<<vec[i]<<" "; } }