精华内容
下载资源
问答
  • 新手画动漫人物如何找人物重心?有人问我动态怎么画?这个问题不是用文字能解答的,只能说一些简单的考试可以用的动态,考站姿就是考动态了,站姿动态怎么出呢?其主要就是腿,腿是最容易出动态的,简单理解就是体块...

    新手画动漫人物如何找人物重心? 有人问我动态怎么画?这个问题不是用文字能解答的,只能说一些简单的考试可以用的动态,考站姿就是考动态了,站姿动态怎么出呢?其主要就是腿,腿是最容易出动态的,简单理解就是体块三角形。

    顺便在此向大家推荐一下:美术集网校(在线授课,电脑、手机APP全部都可以登录学习),主打素描、速写、色彩、手绘动漫、手绘漫画、手绘基础、传统美术等,是一个在国内非常火的绘画学习软件或平台。

    一、动态分析

    肩膀动态线,即左右肩峰的连线;骨盆动态线,即左右股骨大转子连线。肩部与骨盆位于躯干的上、下两端,是躯干连接四肢的肢纽带,它们之间的相互关系显示了人体胸腔体块和骨盆体块的平行、倾斜、旋转的运动变化。人体立正时,肩膀和骨盆动态线呈水平状并相互平行;人体活动时肩膀和骨盆动态线呈反问倾斜;人体跑动时,肩膀和骨盆动态线以脊柱线为轴心前后旋转,这种旋转也可以称为对置,通常是胸廓和肩部在同一方向,而臀部和腿部则扭转到相反的方向。

    二、脊柱分析

    脊柱是人体最重要的支撑结构,是人体运动的枢纽和主要动态。线,主导着头、胸廓和骨盆的运动,同时也协调着人体各部分的运动与平衡。脊柱线的变化决定了人体各部分的位置,并使它们相互协调和具有节奏感。脊柱的弯曲、旋转,形成了人体三体积的仰俯、倾斜和扭动等不同状态和透视变化。人体的弯曲或伸展运动几乎完全在腰椎,体侧运动则是全身性的。

    对转身运动而言,如果脊骨是直立的,则呈现在腰椎;如果脊骨是半弯曲的,则呈现在脊椎的中部;而如果脊骨是完全弯曲,则呈现在脊椎的上部。脊柱在速写里简称为“一竖线”,它在人体正面的表现形式为从颈窝到胸窝,到肚脐,再到耻骨联合这样一条纵线的弯曲变化,这点非常重要,它为我们观察人体正面的动态提供依据。

    三、人物三体积

    人体的头部、胸廓和盆骨三部分的形体可概括成三个立方体,称三体积。三体积的塑造,是人体造型是否具有体积感和重量感的关键。

    四、重心

    支撑人体的关键三大块组合通过脖子和腰部以及四肢的协调形成稳定的平衡重心,重心必须与地面保持垂直关系,动作才能稳定。某种意义上讲,静态站立着的人体如同垂直悬挂的钟表,他和这个钟表一样,是静止不动的。当钟摆成弧形左右摆动时,它的重心总是固定不变的。

    钟摆从重心处呈弧形摆至两侧的极限位置,其远离重心的程度,正相当于人体远离平衡的程度。这个位置体现了最大的运动角度,画中此点为人体运动的最大角度。即使在运动角度达到最大时,动态中也必须有一种稳定感,就像钟摆一样,人体可以重新回到稳定的重心上来。这种平衡感在画面中表现出来的是动作的连贯性和韵律感。

    在不受外力的影响下,一个站立的人体不论他是向前、向后还是向侧面,他的姿态体现在画面上都会是稳定的。重心从脖颈处的胸口落在承重的那只脚上,或同时承重在两只脚之间。当重心落在支撑的一只脚上,支撑腿的胯骨点往往会高于另一侧。

    学画画,本就不是一件轻松的事情,所以大家要努力坚持,努力的去克服各种困难!加油吧~!赠人玫瑰手有余香,祝您好运一生一世,如果你觉得有用,请点赞转发,谢谢^_^!

    展开全文
  • 树的重心定义为树的某个节点,当去掉该节点后,树的各个连通分量中,节点数最多的连通分量其节点数达到最小值。树可能存在多个重心。如下图,当去掉点1后,树将分成两个连通块:(2,4,5),(3,6,7),则最大的连通块...

    前言

    最近在学树形DP,感触颇多。下面就写出来了。

    题目

    问题 C(2078): 求树的重心

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    树的重心定义为树的某个节点,当去掉该节点后,树的各个连通分量中,节点数最多的连通分量其节点数达到最小值。树可能存在多个重心。如下图,当去掉点1后,树将分成两个连通块:(2,4,5),(3,6,7),则最大的连通块包含节点个数为3。若去掉点2,则树将分成3个部分,(4),(5),(1,3,6,7)最大的连通块包含4个节点;第一种方法可以得到更小的最大联通分量。可以发现,其他方案不可能得到比3更小的值了。所以,点1是树的重心。

    输入

    输入:第一行一个整数n,表示树的结点个数。(n<100)

    接下来n-1行,每行两个数i,j。表示i和j有边相连。

    输出

    输出:第一行一个整数k,表示重心的个数。

    接下来K行,每行一个整数,表示重心。按从小到大的顺序给出。

    样例输入

    7
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7

    样例输出

    1
    1

     分析

    此题是很简单的一道题。

    f_{i }表示在这棵树中将节点i删除后最大联通块的大小。

    num_{j}表示节点j子树中的节点个数(num_{j}可以再深搜过程中求得)

    那么f_{i} = max(num{j}) (j\epsilon son_{i})

    不要忘了i的父亲上面还有连通块,所以f_{i}=max(f_{i},num_{i})

    最后统计一下min(f_{i})就可以了

    代码

    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define N 220
    #define LL long long
    #define inf 0x7f7f7f7f
    #define mem(a,n) memset(a,n,sizeof(a))
     
    int read() {
        int f=1,s=0;char a=getchar();
        while(!(a>='0'&&a<='9')) {if(a=='-') f=-1 ; a=getchar(); }
        while(a>='0'&&a<='9') {s=s*10+a-'0'; a=getchar();}
        return f*s;
    }
     
     
    int n,u,v,f[N],num[N],ans,minn=inf;
    vector<int> son[N];
     
    void dfs(int p,int fa) {
        num[p]=1;
        for(int i=0;i<son[p].size();i++) {
            if(son[p][i]==fa)
                continue;
            dfs(son[p][i],p);
            f[p]=max(f[p],num[son[p][i]]);
            num[p]+=num[son[p][i]];
        }
        f[p]=max(f[p],n-num[p]);
    }
     
    int main() {
        n=read();
        for(int i=1,u,v;i<=n-1;i++) {
            u=read();
            v=read();
            son[v].push_back(u);
            son[u].push_back(v);
        }
        dfs(1,0);
        for(int i=1;i<=n;i++)
            if(f[i]<minn)
                minn=f[i];
        for(int i=1;i<=n;i++)
            if(f[i]==minn)
                ans++;
        cout<<ans;
        for(int i=1;i<=n;i++)
            if(f[i]==minn)
                cout<<endl<<i;
    }

     

    展开全文
  • 树的重心 点分治

    2015-07-15 22:09:00
    最近学了下点分治 说道点分治就得先说到树的重心 树的重心的定义是:最大的子树最小的节点。 为什么要找树的重心呢 ...那么如何找重心呢 根据定义,我们不妨维护一下两个数组sz[]和mx[]表示以r...

    最近学了下点分治

    说道点分治就得先说到树的重心

    树的重心的定义是:最大的子树最小的节点。

    为什么要找树的重心呢

    因为找到树的重心把他变成根以后,最大的子树的大小不超过n/2,否则如果超过n/2将该子树的根作为重心将会更优。

    这样可以保证递归的层数不超过logn层,同时保证每个点最多被计算logn次。

     

    那么如何找重心呢

    根据定义,我们不妨维护一下两个数组sz[]和mx[]表示以r为根的子树大小和无根树中的最大子树大小,那么mx最小的那个节点就是重心。

    有两种写法 一种是

    void getroot(int x,int fa)
    {
        son[x]=1;f[x]=0;
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].to==fa||vis[e[i].to])continue;
            getroot(e[i].to,x);
            son[x]+=son[e[i].to];
            f[x]=max(f[x],son[e[i].to]);
        }
        f[x]=max(f[x],sum-son[x]);
        if(f[x]<f[root])root=x;
    }

    另一种写法是用两个函数

    void dfs_size(int x,int fa) {
        sz[x]=1;
        mx[x]=0;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_size(p->to,x);
            sz[x] += sz[p->to];
            maxit(mx[x],sz[p->to]);
        }
    }
    
    int root=0;
    void dfs_root(int r,int x,int fa) {
        maxit(mx[x],sz[r]-sz[x]);
        if(mx[x]<mx[root]) root=x;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_root(r,p->to,x);
        }
    }

    我采用的后者,因为太弱了第一种一开始没看懂。

    我一直觉得只用dfs一次就可以把每个子树的重心找到,后来发现每一棵子树都要找一次orz感觉复杂度一下就上去了

     

    然后有两道找树的重心的题

    poj1655

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cstring>
     6 
     7 using namespace std;
     8 
     9 const int Maxn=20000+10,INF=0x7fffffff;
    10 
    11 struct Edge{
    12     int to;
    13     Edge*next;
    14     Edge(int to=0,Edge* next=0):to(to),next(next){}
    15 }pool[Maxn*2],*fir[Maxn],*pis=pool;
    16 
    17 void AddEdge(int from,int to){
    18     *pis=Edge(to,fir[from]);fir[from]=pis++;
    19     *pis=Edge(from,fir[to]);fir[to]=pis++;
    20 }
    21 
    22 int sz[Maxn],mx[Maxn];
    23 void dfs_size(int x,int fa) {
    24     sz[x]=1;
    25     mx[x]=0;
    26     for(Edge*p=fir[x];p;p=p->next) {
    27         if(p->to==fa) continue;
    28         dfs_size(p->to,x);
    29         sz[x] += sz[p->to];
    30         mx[x]=max(mx[x],sz[p->to]);
    31     }
    32 }
    33 
    34 int root;
    35 
    36 void dfs_root(int r,int x,int fa) {
    37     mx[x]=max(mx[x],sz[r]-sz[x]);
    38     if(mx[root]>mx[x]) root=x;
    39     for(Edge*p=fir[x];p;p=p->next) {
    40         if(p->to==fa) continue;
    41         dfs_root(r,p->to,x);
    42     }
    43 }
    44 
    45 int n;
    46 void init() {
    47     root=0;
    48     mx[0]=INF;
    49     pis=pool;
    50     memset(fir,0,sizeof fir);
    51     for(int i=1;i<n;i++) {
    52         int u,v;
    53         scanf("%d%d",&u,&v);
    54         AddEdge(u,v);
    55     }
    56 }
    57 
    58 int main() {
    59 #ifdef DEBUG
    60     freopen("in.txt","r",stdin);
    61     freopen("out.txt","w",stdout);
    62 #endif
    63     
    64     int T;
    65     for(scanf("%d",&T);T--;) {
    66         scanf("%d",&n);
    67         init();
    68         dfs_size(1,0);
    69         dfs_root(1,1,0);
    70         printf("%d %d\n",root,mx[root]);
    71     }
    72     
    73     return 0;
    74 }
    View Code

     poj3170

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cstring>
     6 
     7 using namespace std;
     8 
     9 const int Maxn=50000+10,INF=0x7fffffff;
    10 
    11 struct Edge{
    12     int to;
    13     Edge*next;
    14     Edge(int to=0,Edge* next=0):to(to),next(next){}
    15 }pool[Maxn*2],*fir[Maxn],*pis=pool;
    16 
    17 void AddEdge(int from,int to){
    18     *pis=Edge(to,fir[from]);fir[from]=pis++;
    19     *pis=Edge(from,fir[to]);fir[to]=pis++;
    20 }
    21 
    22 int sz[Maxn],mx[Maxn];
    23 void dfs_size(int x,int fa) {
    24     sz[x]=1;
    25     mx[x]=0;
    26     for(Edge*p=fir[x];p;p=p->next) {
    27         if(p->to==fa) continue;
    28         dfs_size(p->to,x);
    29         sz[x] += sz[p->to];
    30         mx[x]=max(mx[x],sz[p->to]);
    31     }
    32 }
    33 
    34 int root;
    35 int ans[Maxn],tot;
    36 
    37 void dfs_root(int r,int x,int fa) {
    38     mx[x]=max(mx[x],sz[r]-sz[x]);
    39     if(mx[root]>mx[x]) ans[tot=1]=root=x;
    40     else if(mx[root]==mx[x]) ans[++tot]=x;
    41     for(Edge*p=fir[x];p;p=p->next) {
    42         if(p->to==fa) continue;
    43         dfs_root(r,p->to,x);
    44     }
    45 }
    46 
    47 int n;
    48 void init() {
    49     root=0;
    50     mx[0]=INF;
    51     pis=pool;
    52     memset(fir,0,sizeof fir);
    53     for(int i=1;i<n;i++) {
    54         int u,v;
    55         scanf("%d%d",&u,&v);
    56         AddEdge(u,v);
    57     }
    58 }
    59 
    60 int main() {
    61 #ifdef DEBUG
    62     freopen("in.txt","r",stdin);
    63     freopen("out.txt","w",stdout);
    64 #endif
    65     
    66     for(;~scanf("%d",&n);) {
    67         init();
    68         dfs_size(1,0);
    69         dfs_root(1,1,0);
    70         sort(ans+1,ans+tot+1);
    71         for(int i=1;i<=tot;i++) {
    72             printf("%d%c",ans[i],i==n?'\n':' ');
    73         }
    74     }
    75     
    76     return 0;
    77 }
    View Code

     

    之后做了几道hzwer上的点分治,贴下代码QuQ

    bzoj2152

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    
    using namespace std;
    
    const int Maxn=20005,INF=0x7fffffff;
    struct Edge{
        int to,v;
        Edge*next;
        Edge(int to=0,int v=0,Edge*next=NULL):to(to),v(v),next(next){
            
        }
    }pool[Maxn*2],*fir[Maxn],*pis;
    
    void AddEdge(int from,int to,int v){
        *pis=Edge(to,v,fir[from]);fir[from]=pis++;
        *pis=Edge(from,v,fir[to]);fir[to]=pis++;
    }
    
    int sz[Maxn],mx[Maxn];
    int vis[Maxn],clk;
    void dfs_size(int x,int fa) {
        sz[x]=1;
        mx[x]=0;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_size(p->to,x);
            sz[x] += sz[p->to];
            mx[x] = max(mx[x],sz[p->to]);
        }
    }
    
    int root=0;
    void dfs_root(int r,int x,int fa) {
        mx[x] = max(mx[x],sz[r]-sz[x]);
        if(mx[root]>mx[x]) root=x;
        
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_root(r,p->to,x);
        }
    }
    
    int num[3];
    void dfs_dis(int x,int d,int fa) {
        num[d]++;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_dis(p->to,(d+p->v)%3,x);
        }
    }
    
    int k;
    int calc(int x,int d) {
        int ret=0;
        memset(num,0,sizeof num);
        dfs_dis(x,d,0);
        ret += num[0]*(num[0]-1)/2;
        ret += num[1]*num[2];
        return ret;
    }
    int ans;
    void dfs(int x) {
        dfs_size(x,0);
        root=0;
        dfs_root(x,x,0);
        vis[root]=clk;
        ans += calc(root,0);
        for(Edge*p=fir[root];p;p=p->next) {
            if(vis[p->to]==clk) continue;
            ans -= calc(p->to,p->v);
            dfs(p->to);
        }
    }
    int n;
    void init() {
        memset(mx,0,sizeof mx);
        mx[0]=INF;
        ans=0;
        ++clk;
        memset(fir,0,sizeof fir);
        pis=pool;
        int u,v,w;
        for(int i=1;i<n;i++) {
            scanf("%d%d%d",&u,&v,&w);
            AddEdge(u,v,w%3);
        }
    }
    
    int gcd(int a,int b) {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    int main(){
    #ifdef DEBUG
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
        
        for(;scanf("%d",&n)==1 && n;) {
            init();
            dfs(1);
            int a=ans*2+n,b=n*n;
            int g=gcd(a,b);
            printf("%d/%d\n",a/g,b/g);
        }
        
        return 0;
    }
    View Code

    bzoj3697

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    
    using namespace std;
    typedef long long ll;
    const int Maxn=100005,INF=0x3f3f3f3f;
    struct Edge{
        int to,v;
        Edge*next;
        Edge(int to=0,int v=0,Edge*next=NULL):to(to),v(v),next(next){
            
        }
    }pool[Maxn*2],*fir[Maxn],*pis;
    
    void AddEdge(int from,int to,int v){
        *pis=Edge(to,v,fir[from]);fir[from]=pis++;
        *pis=Edge(from,v,fir[to]);fir[to]=pis++;
    }
    
    int sz[Maxn],mx[Maxn];
    int vis[Maxn],clk;
    void dfs_size(int x,int fa) {
        sz[x]=1;
        mx[x]=0;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_size(p->to,x);
            sz[x] += sz[p->to];
            mx[x] = max(mx[x],sz[p->to]);
        }
    }
    
    int root=0;
    void dfs_root(int r,int x,int fa) {
        mx[x] = max(mx[x],sz[r]-sz[x]);
        if(mx[root]>mx[x]) root=x;
        
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_root(r,p->to,x);
        }
    }
    
    int n;
    int f[Maxn*2+10][2];
    int g[Maxn*2+10][2];
    int t[Maxn*2+10];
    int max_deep;
    #define f(a,b) f[a+n][b]
    #define g(a,b) g[a+n][b]
    #define t(a) t[a+n]
    void dfs_dis(int x,int d,int fa) {
        max_deep=max(max_deep,abs(d));
        if(t(d)++) g(d,1)++;
        else g(d,0)++;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_dis(p->to,d+p->v,x);
        }
        t(d)--;
    }
    
    int k;
    ll ans;
    
    void dfs(int x) {
        int mx=0;
        dfs_size(x,0);
        root=0;
        dfs_root(x,x,0);
        vis[root]=clk;
        f(0,0)=1;
        for(Edge*p=fir[root];p;p=p->next) {
            if(vis[p->to]==clk) continue;
            max_deep=0;
            dfs_dis(p->to,p->v,root);
            mx=max(max_deep,mx);
            ans += 1ll*(f(0,0)-1)*g(0,0);
            for(int i = -max_deep;i <= max_deep;i++) {
                ans += 1ll*f(i,0)*g(-i,1) + f(i,1)*g(-i,0) + f(i,1)*g(-i,1);
            }
            for(int i = -max_deep;i <= max_deep;i++) {
                f(i,0) += g(i,0);
                f(i,1) += g(i,1);
                g(i,0) = g(i,1) = 0;
            }
        }
        for(int i=-mx;i<=mx;i++) f(i,0)=f(i,1)=0;
        for(Edge*p=fir[root];p;p=p->next) {
            if(vis[p->to]!=clk) dfs(p->to);
        }
    }
    void init() {
        max_deep=0;
        memset(mx,0,sizeof mx);
        mx[0]=INF;
        ans=0;
        ++clk;
        memset(fir,0,sizeof fir);
        pis=pool;
        int u,v,w;
        for(int i=1;i<n;i++) {
            scanf("%d%d%d",&u,&v,&w);
            AddEdge(u,v,w==1?1:-1);
        }
    }
    
    int main(){
    #ifdef DEBUG
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
        
        for(;scanf("%d",&n)==1;) {
            init();
            dfs(1);
            cout<<ans<<endl;
        }
        
        return 0;
    }
    View Code

    bzoj1758

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    
    using namespace std;
    typedef long long ll;
    const int Maxn=100005,INF=0x3f3f3f3f;
    const double eps=1e-7;
    int U,L;
    struct Edge{
        int to,v;
        Edge*next;
        Edge(int to=0,int v=0,Edge*next=NULL):to(to),v(v),next(next){
            
        }
    }pool[Maxn*2],*fir[Maxn],*pis;
    
    void AddEdge(int from,int to,int v){
        *pis=Edge(to,v,fir[from]);fir[from]=pis++;
        *pis=Edge(from,v,fir[to]);fir[to]=pis++;
    }
    
    template<typename Q> void maxit(Q&x,const Q&y) {
        if(x<y) x=y;
    }
    
    int sz[Maxn],mx[Maxn];
    int vis[Maxn],clk=0;
    void dfs_size(int x,int fa) {
        sz[x]=1;
        mx[x]=0;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_size(p->to,x);
            sz[x] += sz[p->to];
            maxit(mx[x],sz[p->to]);
        }
    }
    
    int root=0;
    void dfs_root(int r,int x,int fa) {
        maxit(mx[x],sz[r]-sz[x]);
        if(mx[x]<mx[root]) root=x;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_root(r,p->to,x);
        }
    }
    
    int dep[Maxn],fa[Maxn];
    double dis[Maxn],M,ans=0,lim;
    double f[Maxn];
    
    bool check(int x) {
        int up=0;
        for(Edge*p=fir[x];p;p=p->next) {
            if(vis[p->to]==clk) continue;
    //        if(f[0]!=0) exit(1);
            static int q[Maxn],ql,qr;
            ql=qr=0;
            
            fa[x]=0;
            dis[x]=dep[x]=0;
            q[++qr]=p->to;
            fa[p->to]=x;
            dep[p->to]=1;
            dis[p->to]=p->v-M;
            
            for(int u;ql<qr;) {
                u=q[++ql];
                for(Edge*p=fir[u];p;p=p->next) {
                    if(p->to!=fa[u] && vis[p->to]!=clk) {
                        q[++qr] = p->to;
                        fa[p->to]=u;
                        dep[p->to]=dep[u]+1;
                        dis[p->to]=dis[u]+p->v-M;
                    }
                }
            }
            for(int i=up+1;i<=dep[q[qr]];i++) f[i]= -INF;
            static int mq[Maxn],ml,mr;
            ml=mr=0;int now=up;
            for(int i=1;i<=qr;i++) {
                int x=q[i];
                for(;dep[x]+now>=L&&now>=0;now--) {
                    for(;ml<mr && f[mq[mr]] < f[now];mr--);
                    mq[++mr] = now;
                }
                for(;dep[x]+mq[ml+1]>U && ml<mr;ml++);
                if(ml<mr && f[mq[ml+1]] + dis[x]>=-eps) return 1;
            }
            
            for(int i=1;i<=qr;i++) {
                maxit(f[dep[q[i]]],dis[q[i]]);
            }
            maxit(up,dep[q[qr]]);
        }
        return 0;
    }
    
    void dfs(int x) {
        dfs_size(x,0);
        dfs_root(x,x,root=0);
        vis[root]=clk;
        
        double l=ans,r=lim;
        for(;r-l>eps;) {
            M=l+(r-l)/2;
            if(check(root)) l=M;
            else r=M;
        }
        ans=l;
        
        for(Edge*p=fir[root];p;p=p->next) {
            if(!vis[p->to]) dfs(p->to);
        }
    }
    
    int n;
    void init() {
        mx[0]=INF;
        ++clk;
        memset(fir,0,sizeof fir);
        pis=pool;
        
        scanf("%d%d%d",&n,&L,&U);
        for(int i=1;i<n;i++) {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            AddEdge(u,v,w);
            maxit(lim,(double)w);
        }
    }
    
    int main(){
    #ifdef DEBUG
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
        
        init();
        dfs(1);
        printf("%.3lf\n",ans);
        
        return 0;
    }
    View Code

    bzoj3784

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<queue>
      7 
      8 using namespace std;
      9 
     10 const int Maxn=50010,logn=21;
     11 const int nlogn=800000;
     12 const int INF=0x3f3f3f3f;
     13 struct Edge{
     14     int to,v;
     15     Edge*next;
     16     Edge(int to=0,Edge*next=0,int v=0):to(to),v(v),next(next){}
     17 }pool[Maxn*2],*pis=pool,*fir[Maxn];
     18 
     19 void AddEdge(int from,int to,int v) {
     20     *pis=Edge(to,fir[from],v);fir[from]=pis++;
     21     *pis=Edge(from,fir[to],v);fir[to]=pis++;
     22 }
     23 
     24 template<typename Q>void maxit(Q&x,const Q&y) {
     25     if(x<y) x=y;
     26 }
     27 int sz[Maxn],mx[Maxn];
     28 bool vis[Maxn];
     29 void dfs_size(int x,int fa) {
     30     sz[x]=1;
     31     mx[x]=0;
     32     for(Edge*p=fir[x];p;p=p->next) {
     33         if(vis[p->to] || p->to==fa) continue;
     34         dfs_size(p->to,x);
     35         sz[x] += sz[p->to];
     36         maxit(mx[x],sz[p->to]);
     37     }
     38 }
     39 
     40 int root=0;
     41 void dfs_root(int r,int x,int fa) {
     42     maxit(mx[x],sz[r]-sz[x]);
     43     if(mx[x]<mx[root]) root=x;
     44     for(Edge*p=fir[x];p;p=p->next) {
     45         if(vis[p->to] || p->to==fa) continue;
     46         dfs_root(r,p->to,x);
     47     }
     48 }
     49 
     50 int tot;
     51 struct Data2 {
     52     int v,pos;
     53     Data2(int v=0,int pos=0):v(v),pos(pos) {}
     54     Data2 operator + (const Data2&rhs) const {
     55         return v>rhs.v?*this:rhs;
     56     }
     57 }st[nlogn][logn];
     58 
     59 void dfs_dis(int x,int d,int fa) {
     60     ++tot;
     61     st[tot][0] = Data2(d,tot);
     62     for(Edge*p=fir[x];p;p=p->next) {
     63         if(vis[p->to] || p->to==fa) continue;
     64         dfs_dis(p->to,d+p->v,x);
     65     }
     66 }
     67 
     68 int L[nlogn],R[nlogn];
     69 
     70 struct Data {
     71     int id,l,r,v,pos;
     72     bool operator < (const Data& rhs) const {
     73         return v<rhs.v;
     74     }
     75     Data(int id,int l,int r,int v,int pos):id(id),l(l),r(r),v(v),pos(pos) {}
     76     Data() {}
     77 };
     78 
     79 priority_queue<Data> q;
     80 
     81 void st_init() {
     82     for(int i=0;i<=tot;i++) {
     83         for(int j=1;(i+(1<<(j-1)))<=tot;j++) {
     84             st[i][j] = st[i][j-1] + st[i+(1<<(j-1))][j-1];
     85         }
     86     }
     87 }
     88 
     89 Data2 st_query(int l,int r) {
     90     int k=0;
     91     while( ( 1<<(k+1) ) <=r-l+1)k++;//如果2^(k+1)<=R-L+1,则k还可以+1
     92     return st[l][k]+st[r-(1<<k)+1][k];
     93 }
     94 
     95 void dfs(int x) {
     96     dfs_size(x,0);
     97     dfs_root(x,x,root=0);
     98     vis[x=root]=1;
     99     
    100     int s=++tot;
    101     st[tot][0]=Data2(0,tot);
    102     for(Edge*p=fir[x];p;p=p->next) {
    103         if(vis[p->to]) continue;
    104         int t=tot;
    105         dfs_dis(p->to,p->v,x);
    106         for(int i=t+1;i<=tot;i++) {
    107             L[i]=s;
    108             R[i]=t;
    109         }
    110     }
    111     for(Edge*p=fir[x];p;p=p->next) {
    112         if(!vis[p->to]) dfs(p->to);
    113     }
    114 }
    115 
    116 int n,m;
    117 
    118 void init() {
    119     mx[0]=INF;
    120     scanf("%d%d",&n,&m);
    121     for(int i=1;i<n;i++) {
    122         int u,v,w;
    123         scanf("%d%d%d",&u,&v,&w);
    124         AddEdge(u,v,w);
    125     }
    126 }
    127 
    128 //#define dout printf
    129 void work() {
    130     dfs(1);
    131     st_init();
    132     
    133     /*
    134     dout("tot=%d\n",tot);
    135     for(int i=1;i<=tot;i++) {
    136         dout("(%d,%d,%d)\n",st[i][0].v,L[i],R[i]);
    137     }
    138     dout("------------------\n");
    139     for(int i=1;i<=tot;i++) {
    140         for(int j=0;(1<<j)<=tot;j++) {
    141             dout("st[%d][%d]=(%d,%d)",i,j,st[i][j].v,st[i][j].pos);
    142         }
    143         dout("\n");
    144     }*/
    145     
    146     for(int i=1;i<=tot;i++) {
    147 //        if(L[i]==R[i] && L[i]==0) continue;
    148         Data2 tmp=st_query(L[i],R[i]);
    149         q.push(Data(i, L[i],R[i], tmp.v+st[i][0].v, tmp.pos));
    150     }
    151     for(Data s;m--;) {
    152         s=q.top();q.pop();
    153         printf("%d\n",s.v);
    154         if(s.l!=s.pos) {
    155             Data2 t=st_query(s.l,s.pos-1);
    156             q.push(Data(s.id, s.l, s.pos-1, t.v+st[s.id][0].v, t.pos));
    157         }
    158         if(s.r!=s.pos) {
    159             Data2 t=st_query(s.pos+1,s.r);
    160             q.push(Data(s.id, s.pos+1, s.r, t.v+st[s.id][0].v, t.pos));
    161         }
    162     }
    163 }
    164 
    165 
    166 int main() {
    167 #ifdef DEBUG
    168     freopen("in.txt","r",stdin);
    169 //    freopen("out.txt","w",stdout);
    170 #endif
    171     
    172     init();
    173     work(); 
    174     
    175     return 0;
    176 }
    View Code

    bzoj4016

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<vector>
      7 #include<queue>
      8 
      9 using namespace std;
     10 
     11 const int Maxn=30000+10,Maxm=60000+10,INF=0x3f3f3f3f;
     12 typedef pair<int,int> pii;
     13 vector<pii>e[Maxn];
     14 
     15 void AddEdge(int from,int to,int w) {
     16     e[from].push_back(make_pair(to,w));
     17     e[to].push_back(make_pair(from,w));
     18 }
     19 struct Edge{
     20     int to;
     21     Edge*next;
     22     int w;
     23     Edge(int to=0,Edge*next=0,int w=0):to(to),next(next),w(w) {}
     24 }pool[Maxn*2+Maxm*2],*pis=pool,*fir0[Maxn],*fir[Maxn];
     25 
     26 void Add(Edge* fir[],int from,int to,int w) {
     27     *pis=Edge(to,fir[from],w);fir[from]=pis++;
     28 //    *pis=Edge(from,fir[to],w);fir[to]=pis++;
     29 }
     30 
     31 priority_queue<pii,vector<pii>,greater<pii> > q;
     32 int d[Maxn];
     33 bool vis[Maxn];
     34 void Dijkstra() {
     35     memset(d,0x3f,sizeof d);
     36     q.push(make_pair(0,1));
     37     d[1]=0;
     38     for(pii tmp;!q.empty();) {
     39         tmp=q.top();q.pop();
     40         int x=tmp.second;
     41         if(vis[x]) continue;
     42         vis[x]=1;
     43         for(Edge*p=fir0[x];p;p=p->next) {
     44             if(d[x]+p->w < d[p->to]) {
     45                 d[p->to] = d[x]+p->w;
     46                 q.push(make_pair(d[p->to],p->to));
     47             }
     48         }
     49     }
     50 }
     51 
     52 void dfs_path(int x) {
     53     vis[x]=1;
     54     for(Edge*p=fir0[x];p;p=p->next) {
     55         if(!vis[p->to] && d[x]+p->w==d[p->to]) {
     56             Add(fir,x,p->to,p->w);
     57             Add(fir,p->to,x,p->w);
     58             dfs_path(p->to);
     59         }
     60     }
     61 }
     62         
     63 
     64 int sz[Maxn],mx[Maxn];
     65 int root=0;
     66 
     67 template<typename Q> void maxit(Q&x,Q y) {
     68     if(x<y) x=y;
     69 }
     70 
     71 void dfs_size(int x,int fa) {
     72     sz[x]=1;
     73     mx[x]=0;
     74     for(Edge*p=fir[x];p;p=p->next) {
     75         if(vis[p->to] || p->to==fa) continue;
     76         dfs_size(p->to,x);
     77         sz[x] += sz[p->to];
     78         maxit(mx[x],sz[p->to]);
     79     }
     80 }
     81 
     82 void dfs_root(int r,int x,int fa) {
     83     maxit(mx[x],sz[r]-sz[x]);
     84     if(mx[x]<mx[root]) root=x;
     85     for(Edge*p=fir[x];p;p=p->next) {
     86         if(p->to==fa || vis[p->to]) continue;
     87         dfs_root(r,p->to,x);
     88     }
     89 }
     90 
     91 int max_deep,md;
     92 int f[Maxn][2],g[Maxn][2];//[i][0] i条的最大长度 [1]方案数 
     93 int K;
     94 void dfs_dis(int x,int dep,int d,int fa) {
     95     if(dep>K) return;
     96     maxit(max_deep,dep);
     97     maxit(md,dep);
     98     if(g[dep][0]<d) g[dep][0]=d, g[dep][1]=1;
     99     else if(g[dep][0]==d) g[dep][1]++;
    100     
    101     for(Edge*p=fir[x];p;p=p->next) {
    102         if(p->to==fa || vis[p->to]) continue;
    103         dfs_dis(p->to,dep+1,d+p->w,x);
    104     }
    105 }
    106 
    107 int ans1=0,ans2;
    108 void dfs(int x) {
    109     dfs_size(x,0);
    110     dfs_root(x,x,root=0);
    111     vis[x=root]=1;
    112     
    113     max_deep=0;
    114     g[0][0]=f[0][0]=0;
    115     g[0][1]=f[0][1]=1;
    116     
    117     for(Edge*p=fir[x];p;p=p->next) {
    118         if(vis[p->to]) continue;
    119         md=0;
    120         dfs_dis(p->to,1,p->w,x);
    121         
    122         for(int i=1;i<=md;i++) {
    123             if(g[i][0] + f[K-i][0]>ans1) 
    124                 ans1=g[i][0] + f[K-i][0],ans2=0; 
    125             if(g[i][0] + f[K-i][0]==ans1) 
    126                 ans2 += g[i][1] * f[K-i][1];
    127         }
    128         for(int i=1;i<=md;i++) {
    129             if(f[i][0]<g[i][0]) f[i][0]=g[i][0], f[i][1]=0;
    130             if(f[i][0]==g[i][0]) f[i][1] += g[i][1]; 
    131             g[i][0]=-INF;
    132         }
    133     }
    134     for(int i=1;i<=max_deep;i++) f[i][0]=0;
    135     for(Edge*p=fir[x];p;p=p->next) {
    136         if(!vis[p->to]) dfs(p->to);
    137     }
    138 }
    139 
    140 int n,m;
    141 
    142 void init() {
    143     scanf("%d%d%d",&n,&m,&K); K--;
    144     int u,v,w;
    145     for(int i=1;i<=m;i++) {
    146         scanf("%d%d%d",&u,&v,&w);
    147         AddEdge(u,v,w);
    148     }
    149     for(int i=1;i<=n;i++) {
    150         sort(e[i].begin(),e[i].end());
    151         for(int j=e[i].size()-1;j>=0;j--) {
    152             Add(fir0, i, e[i][j].first, e[i][j].second);
    153         }
    154     }
    155     mx[0]=INF;
    156 //    for(int i=0;i<Maxn;i++) f[i][0]=g[i][0]=-INF;
    157 }
    158 
    159 int main() {
    160 #ifdef DEBUG
    161     freopen("in.txt","r",stdin);
    162     freopen("out.txt","w",stdout);
    163 #endif
    164     
    165     init();
    166     memset(vis,0,sizeof vis);
    167     Dijkstra();
    168     memset(vis,0,sizeof vis);
    169     dfs_path(1);
    170     memset(vis,0,sizeof vis);
    171     dfs(1);
    172     printf("%d %d\n",ans1,ans2);
    173     
    174     return 0;
    175 }
    View Code

    bzoj1468

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 
      7 using namespace std;
      8 
      9 const int Maxn=40010,INF=0x3f3f3f3f;
     10 
     11 struct Edge{
     12     int to;
     13     Edge*next;
     14     int w;
     15     Edge(int to=0,Edge*next=0,int w=0):to(to),next(next),w(w) {}
     16 }pool[Maxn*2],*fir[Maxn],*pis=pool;
     17 
     18 void AddEdge(int from,int to,int w) {
     19     *pis=Edge(to,fir[from],w);fir[from]=pis++;
     20     *pis=Edge(from,fir[to],w);fir[to]=pis++;
     21 }
     22 
     23 struct Node{
     24     int s,v,r;
     25     Node*ch[2];
     26     Node(int v=0):v(v){r=rand(),s=1;ch[0]=ch[1]=0;}
     27     void maintain() {
     28         s=1;
     29         if(ch[0]) s += ch[0]->s;
     30         if(ch[1]) s += ch[1]->s;
     31     }
     32     int cmp(int k) {
     33         if(k==v) return -1;
     34         return k<v?0:1;
     35     }
     36 }npool[Maxn],*g,*f,*nps=npool;
     37 
     38 void rotate(Node*&o,int d) {
     39     Node*t=o->ch[d];
     40     o->ch[d]=t->ch[d^1];
     41     t->ch[d^1]=o;
     42     o->maintain();
     43     (o=t)->maintain();
     44 }
     45 
     46 void insert(Node*&o,int x) {
     47     if(!o) {
     48         o=nps++;
     49         *o=Node(x);
     50         return;
     51     }
     52     int d=o->cmp(x);
     53     if(d==-1) d=0;
     54     insert(o->ch[d],x);
     55     if(o->ch[d]->r < o->r) rotate(o,d);
     56     o->maintain();
     57 }
     58 
     59 void remove(Node*&o,int x) {
     60     if(!o) return;
     61     int d=o->cmp(x);
     62     if(d==-1) {
     63         if(!o->ch[0]) o=o->ch[1];
     64         else if(!o->ch[1]) o=o->ch[0];
     65         else {
     66             int d2=o->ch[0]->r < o->ch[1]->r ?0:1;
     67             rotate(o,d2);
     68             remove(o->ch[d2^1],x);
     69         }
     70     }else remove(o->ch[d],x);
     71     if(o) o->maintain();
     72 }
     73 
     74 int rank(Node*o,int x) {
     75     int ans=0;
     76     for(int d;o;o=o->ch[d]) {
     77         d=o->cmp(x);
     78         if(d==-1) d=0;
     79         int s=1;
     80         if(o->ch[0]) s+=o->ch[0]->s;
     81         if(d==1) ans += s;
     82     }
     83     return ans+1;
     84 }
     85 
     86 Node*kth(Node*o,int k) {
     87     for(int d;o;o=o->ch[d]) {
     88         int s=o->ch[0]?o->ch[0]->s:0;
     89         if(k==s+1) return o;
     90         if(k>s) k-= s+1,d=1;
     91         else d=0;
     92     }
     93     return NULL;
     94 }
     95 
     96 Node*Pre(Node*o,int x) {
     97     Node*ans=NULL;
     98     for(int d;o;o=o->ch[d]) {
     99         d=o->cmp(x);
    100         if(d==-1) d=0;
    101         if(d==1) ans=o;
    102     }
    103     return ans;
    104 }
    105 
    106 Node*Sub(Node*o,int x) {
    107     Node*ans=NULL;
    108     for(int d;o;o=o->ch[d]) {
    109         d=o->cmp(x);
    110         if(d==-1) d=1;
    111         if(d==0) ans=o;
    112     }
    113     return ans;
    114 }
    115 
    116 template<typename Q> void maxit(Q&x,const Q&y) {
    117     if(x<y) x=y;
    118 }
    119 int mx[Maxn],sz[Maxn];
    120 bool vis[Maxn];
    121 void dfs_size(int x,int fa) {
    122     sz[x] = 1;
    123     mx[x] = 0;
    124     for(Edge*p=fir[x];p;p=p->next) {
    125         if(vis[p->to] || p->to==fa) continue;
    126         dfs_size(p->to,x);
    127         sz[x] += sz[p->to];
    128     }
    129 }
    130 
    131 int root=0;
    132 void dfs_root(int r,int x,int fa) {
    133     maxit(mx[x],sz[r]-sz[x]);
    134     if(mx[x]<mx[root]) root=x;
    135     for(Edge*p=fir[x];p;p=p->next) {
    136         if(vis[p->to] || p->to==fa) continue;
    137         dfs_root(r,p->to,x);
    138     }
    139 }
    140 
    141 int seq[Maxn],tot;
    142 int K;
    143 void dfs_dis(int x,int d,int fa) {
    144     if(d>K) return;
    145     seq[++tot]=d;
    146     for(Edge*p=fir[x];p;p=p->next) if(!vis[p->to] && p->to!=fa) {
    147         dfs_dis(p->to,d+p->w,x);
    148     }
    149 }
    150 
    151 int ans=0;
    152 
    153 void dfs(int x) {
    154     dfs_size(x,0);
    155     dfs_root(x,x,root=0);
    156     vis[x=root]=1;
    157     
    158     nps=npool;
    159     f=NULL;
    160     insert(f,0);
    161     
    162     for(Edge*p=fir[x];p;p=p->next) if(!vis[p->to]) {
    163         tot=0;
    164         dfs_dis(p->to,p->w,x);
    165         for(int i=1;i<=tot;i++) {
    166             ans += rank(f,K-seq[i]+1)-1;
    167         }
    168         for(int i=1;i<=tot;i++) {
    169             insert(f,seq[i]);
    170         }
    171     }
    172     
    173     for(Edge*p=fir[x];p;p=p->next) if(!vis[p->to]) {
    174         dfs(p->to);
    175     }
    176 }
    177 
    178 void init() {
    179     int n;
    180     scanf("%d",&n);
    181     for(int i=1;i<n;i++) {
    182         int u,v,w;
    183         scanf("%d%d%d",&u,&v,&w);
    184         AddEdge(u,v,w);
    185     }
    186     scanf("%d",&K);
    187     mx[0]=INF;
    188 }
    189 
    190 int main() {
    191 #ifdef DEBUG
    192     freopen("in.txt","r",stdin);
    193 //    freopen("out.txt","w",stdout);
    194 #endif
    195     
    196     init();
    197     dfs(1);
    198     printf("%d\n",ans);
    199     
    200     return 0;
    201 }
    View Code

    poj1741

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    
    using namespace std;
    
    const int Maxn=10005,INF=0x7fffffff;
    struct Edge{
        int to,v;
        Edge*next;
        Edge(int to=0,int v=0,Edge*next=NULL):to(to),v(v),next(next){
            
        }
    }pool[Maxn*2],*fir[Maxn],*pis;
    
    void AddEdge(int from,int to,int v){
        *pis=Edge(to,v,fir[from]);fir[from]=pis++;
        *pis=Edge(from,v,fir[to]);fir[to]=pis++;
    }
    
    int sz[Maxn],mx[Maxn];
    int vis[Maxn],clk;
    void dfs_size(int x,int fa) {
        sz[x]=1;
        mx[x]=0;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_size(p->to,x);
            sz[x] += sz[p->to];
            mx[x] = max(mx[x],sz[p->to]);
        }
    }
    
    int root=0;
    void dfs_root(int r,int x,int fa) {
        mx[x] = max(mx[x],sz[r]-sz[x]);
        if(mx[root]>mx[x]) root=x;
        
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_root(r,p->to,x);
        }
    }
    
    int ds[Maxn],tot;
    void dfs_dis(int x,int d,int fa) {
        ds[++tot]=d;
        for(Edge*p=fir[x];p;p=p->next) {
            if(p->to==fa || vis[p->to]==clk) continue;
            dfs_dis(p->to,d+p->v,x);
        }
    }
    
    int k;
    int calc(int x,int d) {
        int ret=0;
        tot=0;
        dfs_dis(x,d,0);
        sort(ds+1,ds+tot+1);
        int l=1,r=tot;
        for(;l<r;l++) {
            for(;ds[l]+ds[r]>k && l<r; r--);
            ret+=r-l;
        }
        return ret;
    }
            
    
    int ans;
    void dfs(int x) {
        dfs_size(x,0);
        root=0;
        dfs_root(x,x,0);
        vis[root]=clk;
        ans += calc(root,0);
        for(Edge*p=fir[root];p;p=p->next) {
            if(vis[p->to]==clk) continue;
            ans -= calc(p->to,p->v);
            dfs(p->to);
        }
    }
    int n;
    void init() {
        memset(mx,0,sizeof mx);
        mx[0]=INF;
        ans=0;
        ++clk;
        memset(fir,0,sizeof fir);
        pis=pool;
        int u,v,w;
        for(int i=1;i<n;i++) {
            scanf("%d%d%d",&u,&v,&w);
            AddEdge(u,v,w);
        }
    }
    
    int main(){
    #ifdef DEBUG
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
        
        for(;scanf("%d%d",&n,&k)==2 && n &&k;) {
            init();
            dfs(1);
            printf("%d\n",ans);
        }
        
        return 0;
    }
    View Code

    bzoj2599

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<vector>
      8 
      9 using namespace std;
     10 
     11 const int Maxn=200005,INF=0x3f3f3f3f;
     12 struct Edge{
     13     int to,v;
     14     Edge*next;
     15     Edge(int to=0,int v=0,Edge*next=NULL):to(to),v(v),next(next){
     16         
     17     }
     18 }pool[Maxn*2],*fir[Maxn],*pis;
     19 
     20 void AddEdge(int from,int to,int v){
     21     *pis=Edge(to,v,fir[from]);fir[from]=pis++;
     22     *pis=Edge(from,v,fir[to]);fir[to]=pis++;
     23 }
     24 
     25 int sz[Maxn],mx[Maxn];
     26 int vis[Maxn],clk;
     27 void dfs_size(int x,int fa) {
     28     sz[x]=1;
     29     mx[x]=0;
     30     for(Edge*p=fir[x];p;p=p->next) {
     31         if(p->to==fa || vis[p->to]==clk) continue;
     32         dfs_size(p->to,x);
     33         sz[x] += sz[p->to];
     34         mx[x] = max(mx[x],sz[p->to]);
     35     }
     36 }
     37 
     38 int root=0;
     39 void dfs_root(int r,int x,int fa) {
     40     mx[x] = max(mx[x],sz[r]-sz[x]);
     41     if(mx[root]>mx[x]) root=x;
     42     
     43     for(Edge*p=fir[x];p;p=p->next) {
     44         if(p->to==fa || vis[p->to]==clk) continue;
     45         dfs_root(r,p->to,x);
     46     }
     47 }
     48 
     49 int f[2000010];
     50 int g[2000010],seq[Maxn],top;
     51 void dfs_dis(int x,int d,int cnt,int fa) {
     52     if(d>1000000) return;
     53     seq[++top]=d;
     54     g[d]=min(g[d],cnt);
     55     for(Edge*p=fir[x];p;p=p->next) {
     56         if(p->to==fa || vis[p->to]==clk) continue;
     57         dfs_dis(p->to,d+p->v,cnt+1,x);
     58     }
     59 }
     60 
     61 int k;
     62 int ans;
     63 void dfs(int x) {
     64     dfs_size(x,0);
     65     root=0;
     66     dfs_root(x,x,0);
     67     vis[root]=clk;
     68     top=0;
     69     for(Edge*p=fir[root];p;p=p->next) {
     70         if(vis[p->to]==clk) continue;
     71         int l=top;
     72         dfs_dis(p->to,p->v,1,root);
     73         for(int i=l+1;i<=top;i++) if(k-seq[i]>=0) ans=min(ans,f[k-seq[i]]+g[seq[i]]);
     74         for(int i=l+1;i<=top;i++) f[seq[i]]=min(f[seq[i]],g[seq[i]]),g[seq[i]]=INF;
     75         g[0]=0;
     76     }
     77     for(int i=1;i<=top;i++) f[seq[i]]=INF;
     78     f[0]=0;
     79     for(Edge*p=fir[root];p;p=p->next) {
     80         if(vis[p->to]!=clk) dfs(p->to);
     81     }
     82 }
     83 int n;
     84 void init() {
     85     memset(mx,0,sizeof mx);
     86     mx[0]=INF;
     87     ans=INF;
     88     ++clk;
     89     memset(fir,0,sizeof fir);
     90     pis=pool;
     91     int u,v,w;
     92     for(int i=1;i<n;i++) {
     93         scanf("%d%d%d",&u,&v,&w);
     94         AddEdge(u+1,v+1,w);
     95     }
     96 }
     97 
     98 int main(){
     99 #ifdef DEBUG
    100     freopen("in.txt","r",stdin);
    101     freopen("out.txt","w",stdout);
    102 #endif
    103     
    104     memset(f,0x3f,sizeof f);
    105     memset(g,0x3f,sizeof g);
    106     f[0]=g[0]=0;
    107     for(;scanf("%d%d",&n,&k)==2;) {
    108         init();
    109         dfs(1);
    110         printf("%d\n",ans>=n?-1:ans);
    111     }
    112     
    113     return 0;
    114 }
    View Code

     

     

    注意每次的辅助数组f,g清空不能用memset清空所有数字,最好统计两个max_deep来清,这样复杂度才有保证,不然就是平方级的了。

    还有vis数组只是用来标记重心的,以前一直理解错了。

    转载于:https://www.cnblogs.com/showson/p/4649664.html

    展开全文
  • 题目连接 题意:求两凸包重心的最短...如何重心呢? 因为行星是均匀的,可以先随便一个点,连接该点和各个面,得到若干三棱锥 把每个三棱锥等价成一个质点,再求这些质点的重心 质点的重心是质点坐标按质...

    题目连接

    题意:求两凸包重心的最短距离

    分析:
    三维凸包模板

    很显然,最优放置方法就是贴住两个行星的某两个面,而最近距离为各自重心到这两个面的距离
    换句话说,我们可以独立求出两颗星球的“重心到各面的最短距离”,再相加即可

    如何求重心呢?
    因为行星是均匀的,可以先随便找一个点,连接该点和各个面,得到若干三棱锥
    把每个三棱锥等价成一个质点,再求这些质点的重心
    质点的重心是质点坐标按质量加权的平均数
    而质量均匀的三棱锥的重心的坐标为4个顶点坐标的平均数

    tip

    调了半天,发现自己的Cross函数写错了。。。go die

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const double eps=1e-8;
    const double INF=1e30;
    const int N=100;
    struct node{
        double x,y,z;
        node (double xx=0,double yy=0,double zz=0)
        {
            x=xx;y=yy;z=zz;
        }
    };
    
    node operator +(const node &A,const node &B) {return node(A.x+B.x,A.y+B.y,A.z+B.z);}
    node operator -(const node &A,const node &B) {return node(A.x-B.x,A.y-B.y,A.z-B.z);}
    node operator *(const node &A,const double &B) {return node(A.x*B,A.y*B,A.z*B);}
    node operator /(const node &A,const double &B) {return node(A.x/B,A.y/B,A.z/B);}
    
    double Dot(node A,node B) {return A.x*B.x+A.y*B.y+A.z*B.z;}
    node Cross(node A,node B) {return node(A.y*B.z-A.z*B.y,A.z*B.x-A.x*B.z,A.x*B.y-A.y*B.x);}
    
    struct CH3D{
        struct face{
            int a,b,c;
            bool ff;
        };
    
        int n;
        node P[N];
        int num;
        face F[8*N];
        int vis[N][N];
    
        double lenth(node a) {
            return sqrt(Dot(a,a));
        }
        double S2(node a,node b,node c) {
            return lenth(Cross(b-a,c-a));
        }
        double V6(node a,node b,node c,node d) {
            return Dot(d-a,Cross(b-a,c-a));
        }
        int cansee(node a,face f){
            double o=Dot(a-P[f.a],Cross(P[f.b]-P[f.a],P[f.c]-P[f.a]));
            if (o>eps) return 1;
            else return 0;
        }
    
        void deal(int p,int a,int b) {
            int f=vis[a][b];
            face add;
            if (F[f].ff) {
                if (cansee(P[p],F[f]))
                    dfs(p,f);
                else {
                    add.a=b;
                    add.b=a;
                    add.c=p;
                    add.ff=1;
                    vis[b][a]=vis[a][p]=vis[p][b]=num;
                    F[num++]=add;
                }
            }
        }
        //递归搜索所有应该从凸包内删除的面
        void dfs(int p,int now) {
            F[now].ff=0;
            deal(p,F[now].b,F[now].a);    //反着转一圈 
            deal(p,F[now].c,F[now].b);
            deal(p,F[now].a,F[now].c);
        }
        void create() {
            face add;
    
            num=0;
            if (n<4) return;
    
            bool flag=1;
            for (int i=1;i<n;i++) {
                if (lenth(P[i]-P[0])>eps) {
                    swap(P[1],P[i]);
                    flag=0; break;
                }
            }
            if (flag) return;
            flag=1;
            for (int i=2;i<n;i++) {
                if (lenth(Cross(P[1]-P[0],P[i]-P[0]))>eps) {
                    swap(P[2],P[i]);
                    flag=0; break;
                }
            }
            if (flag) return;
            flag=1;
            for (int i=3;i<n;i++) {
                if (fabs(Dot(P[i]-P[0],Cross(P[1]-P[0],P[2]-P[0])))>eps) {
                    swap(P[3],P[i]);
                    flag=0; break;
                }
            }
            if (flag) return;
    
            for (int i=0;i<4;i++)
            {
                add.a=(i+1)%4;
                add.b=(i+2)%4;
                add.c=(i+3)%4;
                add.ff=1;
                if (cansee(P[i],add)) swap(add.b,add.c);    // 
                vis[add.a][add.b]=vis[add.b][add.c]=vis[add.c][add.a]=num;
                F[num++]=add;
            }
            for (int i=4;i<n;i++)
                for (int j=0;j<num;j++)
                    if (F[j].ff&&cansee(P[i],F[j])) {
                        dfs(i,j);
                        break;    //
                    }
            int tmp=num;
            for (int i=num=0;i<tmp;i++)
                if (F[i].ff)
                    F[num++]=F[i];
        }
    
        double Ssum() {
            double ans=0;
            if (n==3) {
                ans=S2(P[0],P[1],P[2]);
                return ans/2.0;
            }
            for (int i=0;i<num;i++)
                ans+=S2(P[F[i].a],P[F[i].b],P[F[i].c]);
            return ans/2.0;
        }
        double Vsum() {
            double ans=0;
            node tmp(0,0,0);
            for (int i=0;i<num;i++)
                ans+=V6(tmp,P[F[i].a],P[F[i].b],P[F[i].c]);
            return fabs(ans)/6.0;
        }
        node centre() {
            node ans(0,0,0),o(0,0,0);
            double all=0;
            for (int i=0;i<num;i++)
            {
                double vol=V6(o,P[F[i].a],P[F[i].b],P[F[i].c]);
                ans=ans+(o+P[F[i].a]+P[F[i].b]+P[F[i].c])/4.0*vol;
                all+=vol;
            }
            ans=ans/all;
            return ans;
        } 
        double dis_face(node p,int i) {
            return fabs(V6(P[F[i].a],P[F[i].b],P[F[i].c],p)/lenth(Cross(P[F[i].b]-P[F[i].a],P[F[i].c]-P[F[i].a])));
        }
        double getmin() {
            node p=centre();
            double ans=INF;
            for (int i=0;i<num;i++)
            {
                double t=dis_face(p,i);
                if (t-ans<eps) ans=t;
            }
            return ans;
        }
    };
    
    CH3D hull;
    int main() {
        while (scanf("%d",&hull.n)!=EOF) {
            for(int i=0; i<hull.n; i++) scanf("%lf %lf %lf",&hull.P[i].x,&hull.P[i].y,&hull.P[i].z);
            hull.create();
            double ans=0;
            ans=hull.getmin(); 
    
            scanf("%d",&hull.n);
            for(int i=0; i<hull.n; i++) scanf("%lf %lf %lf",&hull.P[i].x,&hull.P[i].y,&hull.P[i].z);
            hull.create();
            ans+=hull.getmin();
            printf("%lf\n",ans); 
        }
        return 0;
    }
    展开全文
  • leaflet-计算地图边界的重心点经纬度

    千次阅读 2018-12-20 20:31:12
    这两天在给公司做开发的时候,遇到一个需求:标出1000多个村的重心点位置(就是确定一点在村的中心位置的坐标)。以前在做安徽省内的系统时,村子没有那么...于是乎我就在想如何让代码自己去找重心的位置,这样又快又准...
  • 分析:不难发现,最有放置方法是贴住俩颗行星的某俩个面,而最近距离为各自重心到这...如何重心呢?因为行星是均匀的,可以先随便一个位于 行星内部的点(比如所有顶点的坐标平均数),连接该点和各个面,得到若干
  • 传送门 调了两个小时,终于过了…… ...考虑size已知时如何找重心:一开始设答案在\(x\),若存在\(x\)的一个子节点\(v\),使\(size_v>sum-size_v\),即\(2size_v>sum\),就往\(v\)走,重复该过程,直到走不...
  • 如何发展自己的技术变现 把技术重心放在一些主流,高级,比较有挑战性的技术上 帮助身边朋友解决技术难题(可以一些外包有技术含量的) 扩展自己的朋友圈,融入进优秀的朋友圈中(群或者github项目,主动发言) ...
  • 如何做好技术积累

    2008-04-14 08:47:00
    技术经理跟他们的团队合作,帮助他们通过实验如何更好的工作;当找到改进方式以后,经理们可以让其他团队快速学到他们的做法……简而言之,他们的重心是改进整个组织的潜力和生产力,从而为创造有价值的产品做出...
  • 这是一个困扰我许久的问题。我在mac下开发前端代码,自从html5开发成为工作重心,chrome浏览器逐渐替代了firefox成为首选浏览器。...windows和mac下面都有好多host切换工具,你也可以到npm里去一些模块...
  • 给你下面这样的网站首页,让你视觉层面的问题,你会怎么阐述?(注意:本文只讨论视觉层面问题。)我个人觉得会有三种不同类型的设计师:1.感觉型他说:我感觉这个页面太乱。你问他乱在哪里,他说不出来,仅仅是...
  • 在阿里的微信营销号里看到这样一篇文章,对我稍有感触: 在浩大的软件世界里,作为一名普通程序员,显得十分渺小,甚至会感到...人之所以迷茫往往是不到工作生活的重心,感受不到工作或生活的价值。那么什
  • 前端如何伪造自己想要的接口数据-json数据 场景,最近在做一个vue的大项目,但是没有数据借口啊!也没有自己想要的那个属性,想到的第一种方法居然是用node.js去爬取网页的那些数据,再传到数据库,再写接口,虽然...
  • 出您所在的地区是否值得一试 您可以使用以下URL格式查找任何地区: : 对于单区州(?) 概述 查找您的区域边界(地址搜索) 您的区域边界的这一部分特别有趣。 为什么将这些块放入而将其他块取出? 单击此行...
  • 许多人觉得是直播颜值的问题,于是商家们了帅哥美女来镇场,但转化率却依旧不见增长,这是怎么回事呢?这是因为,电商直播的重心跟普通直播不一样,电商直播在于推荐产品卖货,核心在于商品转化;而普通直播靠的是...
  • 这次需要的是制作一个贴吧的关键词搜索相关帖子的工具,开始以为百度贴吧没有“全吧搜索”这样的功能,后面发现是我多虑了,于是把重心转移到了可视化小程序的制作方面,爬虫相关逻辑则直接了现成的.......

空空如也

空空如也

1 2 3 4
收藏数 69
精华内容 27
关键字:

如何找重心