标签:journey spring number vector exists sim find nec compute
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 3588 | Accepted: 1159 |
Description
Input
Output
Sample Input
6 2 5 3 7 4 1 0 0 5 2 6 3 0 0 0 0 1 8 13 14 0 0
Sample Output
AYE AYE NAY AYE .
题意:判断树上是否有两点的距离正好等于K
思路:分治法:树上的重心分解
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> #include<vector> #include<cstring> #include<string> #include <utility> #include<cmath> using namespace std; const int INF = 0x3f3f3f3f; const int N_MAX = 10000 + 20; struct edge { int to, length; edge(int to=0,int length=0):to(to),length(length) {} }; int n, k; bool centroid[N_MAX]; int subtree_size[N_MAX]; int ans; vector<edge>G[N_MAX]; void init( int n) { for (int i = 1; i <= n; i++) { G[i].clear(); } //memset(subtree_size,0,sizeof(subtree_size)); } int compute_subtree_size( int v, int p) { int c = 1; for (int i = 0; i < G[v].size();i++) { int w = G[v][i].to; if (w == p || centroid[w])continue; c += compute_subtree_size(w, v); } subtree_size[v] = c; return c; } pair<int, int>search_centroid( int v,int p, int t) { pair<int, int>res = make_pair(INF,-1); int s = 1,m=0; for (int i = 0; i < G[v].size(); i++) { int w = G[v][i].to; if (w == p || centroid[w])continue; res = min(res, search_centroid(w, v, t)); m = max(m, subtree_size[w]); s += subtree_size[w]; } m = max(m, t - s); res = min(res,make_pair(m,v)); return res; } void enumerate_paths( int v, int p, int d,vector<int>&ds) { ds.push_back(d); for (int i = 0; i < G[v].size();i++) { int w = G[v][i].to; if (w == p || centroid[w])continue; enumerate_paths(w,v,d+G[v][i].length,ds); } } int count_pairs(vector<int>&ds) { int res = 0; sort(ds.begin(), ds.end()); int j = ds.size(); for (int i = 0; i <ds.size();i++) { while (j > 0 && ds[i] + ds[j-1] > k)j--; res += j - (j > i ? 1 : 0); } j = ds.size(); for (int i = 0; i < ds.size();i++) { while (j > 0 && ds[i] + ds[j - 1] >= k)j--; res -= j - (j > i ? 1 : 0); } return res; } void solve_subproblem( int v) { compute_subtree_size(v, -1); int s = search_centroid(v, -1, subtree_size[v]).second; centroid[s] = true; for (int i = 0; i < G[s].size();i++) { if (centroid[G[s][i].to])continue; solve_subproblem(G[s][i].to); } static vector<int>ds; ds.clear(); ds.push_back(0); for (int i = 0; i < G[s].size();i++) { if (centroid[G[s][i].to])continue; static vector<int>tds; tds.clear(); enumerate_paths(G[s][i].to,s,G[s][i].length,tds); ans -= count_pairs(tds); ds.insert(ds.end(), tds.begin(), tds.end()); } ans += count_pairs(ds); centroid[s] = false; } int main() { while (scanf("%d",&n)&&n) { init(n); for (int i = 1; i <= n;i++) { int to, cost; while (scanf("%d", &to) && to) { scanf("%d",&cost); G[i].push_back(edge (to,cost )); G[to].push_back(edge( i,cost )); } } while (scanf("%d",&k)&&k) { ans = 0; solve_subproblem(1); puts(ans>0?"AYE":"NAY"); } puts("."); } return 0; }
标签:journey spring number vector exists sim find nec compute
原文地址:https://www.cnblogs.com/ZefengYao/p/9064499.html