1. 程式人生 > >hiho1041 - 樹,遍歷

hiho1041 - 樹,遍歷

con 鏈接 二維 amp i++ logs 數組存儲 cst ons

題目鏈接

給一棵樹,給一個序列,問能不能按這個序列遍歷這棵樹,滿足每條邊最多經過兩次。

--------------------------------------------------------------------------

因為數據小,所以直接用二維數組存儲邊,同時用這個數組記錄邊的訪問次數。

因為是樹,任意兩個頂點間的路徑只有一條,所以問題簡單了很多

依次處理給定的序列,從一個頂點dfs到另一個頂點的同時檢查該路徑上的邊是否訪問超過兩次了,如果超過兩次則返回false

#include <set>
#include <map>
#include <stack>
#include 
<queue> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define MAX(a,b) ((a)>=(b)?(a):(b)) #define MIN(a,b) ((a)<=(b)?(a):(b)) #define OO 0x0fffffff using
namespace std; typedef long long LL; const int N = 128; int maze[N][N]; bool vis[N]; int n,m; bool dfs(int s,int e){ vis[s] = true; for(int i=1;i<=n;i++){ if(maze[s][i]&&(!vis[i])){ if(i==e||dfs(i,e)) { if(maze[s][i]>=3) return false; maze[s][i]
++; maze[i][s]++; return true; } } } return false; } int main(){ int t; int a,b,c; int epos,spos; for(scanf("%d",&t);t--;){ scanf("%d",&n); memset(maze,0,sizeof(maze)); for(int i=1;i<n;i++){ scanf("%d%d",&a,&b); maze[a][b] = maze[b][a] = 1; } cin>>m; epos = 1; bool flag = true; while(m--){ spos = epos; scanf("%d",&epos); if(flag){ memset(vis,false,sizeof(vis)); flag = dfs(spos,epos); } } if(flag) puts("YES"); else puts("NO"); } return 0; }

hiho1041 - 樹,遍歷