POJ 2114 Boatherds 点分治

来源:互联网 发布:sql修改字段类型 编辑:程序博客网 时间:2024/06/05 06:38

问是否存在长度等于K的路径。就是将统计小于等于K的换成统计等于K的条数,只要最后统计出来的等于K的数量大于0就是存在。其他一点没变,还是那个论文题的点分治。

//      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,ntemplate<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,在几颗子树之间的答案。其次就是如果算重的话,要将同一棵子树上面的答案消除。

0 0
原创粉丝点击