3365: [Usaco2004 Feb]Distance Statistics 路程统计 点分治

来源:互联网 发布:照片眨眼张嘴软件 编辑:程序博客网 时间:2024/06/02 04:29

听说有点分治裸题来水了一发。。回去继续搞K-D tree了。。

#include<iostream>#include<cstdio>#include<algorithm>#define inf 1000000007#define N 80005using namespace std;int mx[N],size[N],stack[N],dis[N];bool vis[N];int head[N],next[N<<1],key[N<<1],list[N<<1];int n,m,K,cnt,root,sum,ans,top;inline int read(){    int a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}inline void insert(int x,int y,int z){    next[++cnt]=head[x];    head[x]=cnt;    list[cnt]=y;    key[cnt]=z;}void getroot(int x,int fa){    size[x]=1; mx[x]=0;    for (int i=head[x];i;i=next[i])        if (list[i]!=fa&&!vis[list[i]])        {            getroot(list[i],x);            size[x]+=size[list[i]];            mx[x]=max(mx[x],size[list[i]]);        }    mx[x]=max(mx[x],sum-size[x]);    if (mx[x]<mx[root]) root=x;}void getdeep(int x,int fa){    stack[++top]=dis[x];    for (int i=head[x];i;i=next[i])        if (list[i]!=fa&&!vis[list[i]])        {            dis[list[i]]=dis[x]+key[i];            getdeep(list[i],x);        }}inline int calc(int x,int now){    dis[x]=now; top=0;    getdeep(x,0);    sort(stack+1,stack+top+1);    int ans=0,l=1,r=top;    while (l<r)        if (stack[l]+stack[r]<=K) ans+=r-l,l++; else r--;    return ans;}void solve(int x){    ans+=calc(x,0);    vis[x]=1;    for (int i=head[x];i;i=next[i])        if (!vis[list[i]])        {            ans-=calc(list[i],key[i]);            root=0; sum=size[list[i]];            getroot(list[i],0);            solve(root);        }}int main(){    n=read(); m=read();    for (int i=1;i<=m;i++)    {        int u=read(),v=read(),w=read();        insert(u,v,w); insert(v,u,w);    }    K=read(); mx[0]=n;    root=0; sum=n;    getroot(1,0);    solve(root);    cout << ans << endl;    return 0;}
0 0
原创粉丝点击