日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

zzuli-2525-咕咕的搜索序列(思维+DFS)

發布時間:2023/12/9 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。