변 분

3917 단어 나무.알고리즘
설명 하 다.
나무의 분 치 는 점 과 비슷 하 다. 매번 에 양쪽 노드 의 수량 이 상대 적 으로 가 까 운 한 변 (중심 과 비슷 하 다) 을 찾 은 다음 에 이 변 을 통과 하 는 경 로 를 고려 한 다음 에 변 의 양쪽 을 각각 고려한다.국화 그림 에 대해 직접 변 분 하면 복잡 도 는 O (logn) 에서 O (n) 로 퇴화 될 것 이다. 따라서 변 분 하기 전에 rebuild: 각 노드 의 아들 노드 개 수 를 통계 해 야 한다. 만약 에 S (보통 2 이 고 실제 상황 에 따라 조정 할 수 있다) 보다 크 면 아들 노드 에서 S 개의 허 점 으로 바 꾸 고 그들 과 허 변 을 연결 해 야 한다.원래 의 아들 노드 는 평균 적 으로 S 개의 허 점 아래 에 분배 되 었 다. 원래 의 아들 노드 와 허 점 의 변 은 바로 그들 과 원래 의 아버지 노드 간 의 변 이 고 허 점 의 점 권 과 허 변 의 변 권 은 실제 상황 에 따라 조정 된다.점 에 비해 매번 원래 의 나 무 를 두 개 로 나 누고 점 수 는 여러 개 로 나 누 어 처리 하기 가 상대 적 으로 쉬 우 며 rebuild 를 해 야 한 다 는 단점 이 있어 상수 가 상대 적 으로 크다.
코드
#define P pair<int,int>
#define mp make_pair
#define fi first
#define se second
inline void rebuild()
{
    memset(first,-1,sizeof(first)),bb=1;
    int i,j,p,q;
    for(i=1; i<=n; i++)
    {
        if(son[i].size()<=2)
        {
            for(j=0; jelse
        {
            p=++n,q=++n;
            for(j=0; jif(j&1) son[p].push_back(son[i][j]),qn[p].push_back(qn[i][j]);
                else son[q].push_back(son[i][j]),qn[q].push_back(qn[i][j]);
            }
            son[i].clear(),qn[i].clear();
            son[i].push_back(p),son[i].push_back(q);
            qn[i].push_back(0),qn[i].push_back(0);
            ad(i,p,0),ad(i,q,0);
        }
    }
}

void gs(int now,int last)
{
    int p,q;
    size[now]=1;
    for(p=first[now]; p!=-1; p=bn[p].next)
    {
        if(vis[p>>1] || bn[p].to==last) continue;
        gs(bn[p].to,now);
        size[now]+=size[bn[p].to];
    }
}

P gr(int now,int last,int tot)
{
    int p,q;
    P res=mp(tot,0);
    for(p=first[now]; p!=-1; p=bn[p].next)
    {
        if(vis[p>>1] || bn[p].to==last) continue;
        res=min(res,gr(bn[p].to,now,tot));
        res=min(res,mp((int)abs(tot-size[bn[p].to]*2),(int)(p>>1)));
    }
    return res;
}

좋은 웹페이지 즐겨찾기