zzuli-2525-咕咕的搜索序列(思维+DFS)
生活随笔
收集整理的這篇文章主要介紹了
zzuli-2525-咕咕的搜索序列(思维+DFS)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這道題是2019CCPC河南省省賽的H題,當時沒做出來,賽后聽學長講了講思路,發現其實也不難。比賽的時候寫了一個假算法。感覺沒有問題,我就寫到后面了。如果有大佬能夠指出錯誤,感激不盡。
題目鏈接:http://acm.zzuli.edu.cn/problem.php?id=2525
題目大意:中文題。
思路:按照給出的答案序列對樹上的節點進行優先級劃分。然后DFS遍歷的時候優先遍歷高優先級的(出現位置靠前的)。然后得出DFS序列后和Ans比較即可。
ACCode:
//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h> #include<string.h> #include<math.h> #include<map> #include<set> #include<deque> #include<queue> #include<stack> #include<bitset> #include<string> #include<fstream> #include<iostream> #include<algorithm> using namespace std; #define ll long long #define Pair pair<int,int> #define M_P(a,b) make_pair(a,b) //#define max(a,b) (a)>(b)?(a):(b) //#define min(a,b) (a)<(b)?(a):(b) #define clean(a,b) memset(a,b,sizeof(a))// ?? //std::ios::sync_with_stdio(false); // register const int MAXN=1e6+10; const int INF32=0x3f3f3f3f; const ll INF64=0x3f3f3f3f3f3f3f3f; const ll MOD=1e9+7; const double PI=acos(-1.0); const double EPS=1.0e-8;vector<int> Vec[MAXN]; int Pre[MAXN],Vis[MAXN]; int Ans[MAXN],tot; int a[MAXN],b[MAXN]; int n,m;void Intt(){for(int i=1;i<=n;++i){Vec[i].clear();Pre[i]=-1;Vis[i]=0;}tot=0; } void DFS(int u,int fa){int len=Vec[u].size();for(int i=0;i<len;++i){DFS(Vec[u][i],u);}Ans[++tot]=u; } void Mark(int x){while(1){if(Pre[x]==-1||Vis[x]) break;Vis[x]=1;Vec[Pre[x]].push_back(x);x=Pre[x];} } int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);Intt();for(int i=1;i<n;++i){scanf("%d",&a[i]);Pre[i+1]=a[i];}for(int i=1;i<=m;++i) scanf("%d",&b[i]);for(int i=1;i<=m;++i) Mark(b[i]);DFS(1,-1);int i,j;for(i=1,j=1;i<=m&&j<=tot;++j){if(b[i]==Ans[j]){++i;}}//cout<<i<<" "<<j<<endl;if(i<=m) printf("BAD GUGU\n");else printf("NOT BAD\n");} }下面的就是我當時想出的假算法:
思路是,用DFS序處理出節點子樹的范圍,然后每當讀入一個節點的時候,將它所在的子樹都標記(砍掉)。然后讀入節點的時候判斷該節點是否在被砍掉的子樹中(DFS序標記的區間)。如果在被砍掉的區間內,不符合要求,反之繼續,直到遍歷所有的b數組。
Code:
//#pragma comment(linker, "/STACK:1024000000,1024000000")#include<stdio.h> #include<string.h> #include<math.h> #include<map> #include<set> #include<deque> #include<queue> #include<stack> #include<bitset> #include<string> #include<fstream> #include<iostream> #include<algorithm> using namespace std; #define ll long long #define Pair pair<int,int> #define M_P(a,b) make_pair(a,b) //#define max(a,b) (a)>(b)?(a):(b) //#define min(a,b) (a)<(b)?(a):(b) #define clean(a,b) memset(a,b,sizeof(a))// ?? //std::ios::sync_with_stdio(false); // register const int MAXN=1e6+10; const int INF32=0x3f3f3f3f; const ll INF64=0x3f3f3f3f3f3f3f3f; const ll MOD=1e9+7; const double PI=acos(-1.0); const double EPS=1.0e-8;struct Node{int v,val,nxt;Node(int _v=0,int _val=0,int _nxt=0){v=_v;val=_val;nxt=_nxt;} }; Node Edge[MAXN<<1]; int Head[MAXN],Ecnt; int L[MAXN],R[MAXN],tot; int Vis[MAXN]; int a[MAXN],b[MAXN]; int n,m;void Intt(){for(int i=1;i<=n+10;++i){Head[i]=-1;Vis[i]=0;}tot=0;Ecnt=0; } void Add(int u,int v,int val){Edge[Ecnt]=Node(v,val,Head[u]);Head[u]=Ecnt++; } void DFS(int u,int fa){L[u]=++tot;for(int i=Head[u];i+1;i=Edge[i].nxt){int temp=Edge[i].v;DFS(temp,u);}R[u]=tot; } int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);Intt();for(int i=1;i<n;++i){scanf("%d",&a[i]);Add(a[i],i+1,1);}DFS(1,-1); // for(int i=1;i<=n;++i){ // cout<<L[i]<<" "<<R[i]<<endl; // }for(int i=1;i<=m;++i){scanf("%d",&b[i]);}int flag=1;for(int i=1;i<=m;++i){int x=b[i];if(Vis[L[x]]){//該點被標記了 //L[x]表示的是該節點的起始位置,如果這個位置被砍掉了,后面的必定也被砍掉了 flag=0;break;}for(int j=L[x];j<=R[x];++j){ // if(Vis[j]==-1) j=R[j];Vis[j]=1;}}if(flag==0) printf("BAD GUGU\n");else printf("NOT BAD\n");} }/*10 5 1 1 1 2 2 3 4 4 8 8 9 4 6 10*/?
總結
以上是生活随笔為你收集整理的zzuli-2525-咕咕的搜索序列(思维+DFS)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(2865):公开课封装组件库介
- 下一篇: 常用软件收集