POJ 2114 Boatherds 点分治
2015-07-16 09:43
459 查看
问是否存在长度等于K的路径。就是将统计小于等于K的换成统计等于K的条数,只要最后统计出来的等于K的数量大于0就是存在。其他一点没变,还是那个论文题的点分治。
玮神告诉我所以分治算法的精髓都在于合并的过程,树分治也是同样的。
树分治的难点在于怎么计算跨过root,在几颗子树之间的答案。其次就是如果算重的话,要将同一棵子树上面的答案消除。
[code]// whn6325689 // Mr.Phoebe // http://blog.csdn.net/u013007900 #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> #include <functional> #include <numeric> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define eps 1e-9 #define PI acos(-1.0) #define INF 0x3f3f3f3f #define LLINF 1LL<<62 #define speed std::ios::sync_with_stdio(false); typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<ll, ll> pll; typedef complex<ld> point; typedef pair<int, int> pii; typedef pair<pii, int> piii; typedef vector<int> vi; #define CLR(x,y) memset(x,y,sizeof(x)) #define CPY(x,y) memcpy(x,y,sizeof(x)) #define clr(a,x,size) memset(a,x,sizeof(a[0])*(size)) #define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size)) #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define lowbit(x) (x&(-x)) #define MID(x,y) (x+((y-x)>>1)) #define ls (idx<<1) #define rs (idx<<1|1) #define lson ls,l,mid #define rson rs,mid+1,r #define root 1,1,n template<class T> inline bool read(T &n) { T x = 0, tmp = 1; char c = getchar(); while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar(); if(c == EOF) return false; if(c == '-') c = getchar(), tmp = -1; while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar(); n = x*tmp; return true; } template <class T> inline void write(T n) { if(n < 0) { putchar('-'); n = -n; } int len = 0,data[20]; while(n) { data[len++] = n%10; n /= 10; } if(!len) data[len++] = 0; while(len--) putchar(data[len]+48); } //----------------------------------- const int MAXN=10010; struct Edge { int to,nex,c; }e[MAXN<<1]; int head[MAXN],tot; bool vis[MAXN]; int siz[MAXN],dep[MAXN],num[MAXN]; int s[MAXN]; int n,k,tot_size; int rot,top,ans; void init() { tot=ans=rot=0; CLR(head,-1);CLR(vis,0); num[0]=n;tot_size=n; } void addedge(int u,int v,int c) { e[tot].to=v; e[tot].nex=head[u]; e[tot].c=c; head[u]=tot++; } void get_root(int u,int fa=-1) { siz[u]=1;num[u]=0; int v; for(int i=head[u];~i;i=e[i].nex) { v=e[i].to; if(!vis[v] && v!=fa) { get_root(v,u); siz[u]+=siz[v]; num[u]=max(num[u],siz[v]); } } num[u]=max(num[u],tot_size-siz[u]); if(num[u]<num[rot]) rot=u; } void get_dep(int u,int fa=-1) { if(dep[u]<=k) s[top++]=dep[u]; siz[u]=1; int v; for(int i=head[u];~i;i=e[i].nex) { v=e[i].to; if(!vis[v]&&v!=fa) { dep[v]=dep[u]+e[i].c; get_dep(v,u); siz[u]+=siz[v]; } } } int getsum(int u,int len) { dep[u]=len;top=0; get_dep(u); sort(s,s+top); int ans=0; for(int l=0,r=top-1;l<r;l++) { while(l<r && s[l]+s[r]>k) r--; ans+=r-l; } for(int l=0,r=top-1;l<r;l++) { while(l<r && s[l]+s[r]>=k) r--; ans-=r-l; } return ans; } void dfs(int u,int fa=-1) { vis[u]=1; ans+=getsum(u,0); int v; for(int i=head[u];~i;i=e[i].nex) { v=e[i].to; if(!vis[v]&&v!=fa) { ans-=getsum(v,e[i].c); rot=0;tot_size=siz[v]; get_root(v); dfs(rot); } } } int main() { while(read(n) && n) { init(); for(int u=1,v,w;u<=n;u++) { while(read(v) && v) { read(w); addedge(u,v,w); addedge(v,u,w); } } while(read(k) && k) { ans=0,tot_size=n,rot=0; CLR(vis,0); get_root(1); dfs(rot); puts(ans?"AYE":"NAY"); } puts("."); } return 0; }
玮神告诉我所以分治算法的精髓都在于合并的过程,树分治也是同样的。
树分治的难点在于怎么计算跨过root,在几颗子树之间的答案。其次就是如果算重的话,要将同一棵子树上面的答案消除。
相关文章推荐
- Android ant自动打包APK
- Android ListView滑动过程中图片显示重复错位闪烁问题解决
- 简单实现Redis缓存中的排序功能(三)
- jQuery之常用且重要方法
- O2O的攻坚战役:美团如何应对百度腾讯夹击?
- Volatile
- RB树
- 【c++】【vector】
- 【java并发】juc高级锁机制探讨
- 用Redis作为Mysql数据库的缓存(二)
- JAVA NIO 中的 zerocopy 技术提高IO性能
- 【MyBatis框架】SqlMapConfigl配置文件之常用的setting设置
- vsftpd移植到arm问题
- 数据结构基础 之 二叉堆实现堆排序
- eclipse中在线安装FindBugs
- TEA和QQTEA
- asp.net 常用知识点汇总整理
- 机器学习和统计模型的差异
- C++四种强制转换
- Step into Kotlin - 14 - 继承