[JLOI2009]二叉树问题
对于求深度和宽度都很好维护。深度dfs时维护就行,宽度统计同一个深度的节点有多少个,然后取max。
对于求距离,我刚开始以为是要走到根节点在回来,然后固输了(dep[u] - 1) * 2 + dep[v] - 1,结果竟然得了80分,数据有点水过头了……
实际上就是求LCA,然而因为只求一次,所以暴力就行啦~~
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<stack> 8 #include<queue> 9 #include<vector> 10 #include<cctype> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 105; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) putchar('-'), x = -x; 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 int n, s, t; 37 vector<int> v[maxn]; 38 39 int dep[maxn], fa[maxn]; 40 bool vis[maxn]; 41 void dfs(int now) 42 { 43 vis[now] = 1; 44 for(int i = 0; i < (int)v[now].size(); ++i) 45 { 46 if(!vis[v[now][i]]) 47 { 48 dep[v[now][i]] = dep[now] + 1; 49 fa[v[now][i]] = now; 50 dfs(v[now][i]); 51 } 52 } 53 } 54 55 int cnt[maxn], Max_dep = -1, Max_wid = -1; 56 57 int lca(int x, int y) 58 { 59 int ret = 0; 60 while(x != y) 61 { 62 if(dep[x] >= dep[y]) {x = fa[x]; ret += 2;} //一定要有等于,否则同一深度就无限循环了 63 else if(dep[x] < dep[y]) {y = fa[y]; ret++;} 64 } 65 return ret; 66 } 67 68 int main() 69 { 70 n = read(); 71 for(int i = 1; i < n; ++i) 72 { 73 int x = read(), y = read(); 74 v[x].push_back(y); v[y].push_back(x); 75 } 76 s = read(); t = read(); 77 dep[1] = 1; 78 dfs(1); 79 for(int i = 1; i <= n; ++i) 80 { 81 Max_dep = max(Max_dep, dep[i]); 82 Max_wid = max(Max_wid, ++cnt[dep[i]]); 83 } 84 write(Max_dep); enter; write(Max_wid); enter; 85 write(lca(s, t)); 86 // write(((dep[s] - 1 ) << 1) + dep[t] - 1); enter; 87 return 0; 88 }