【BZOJ 4016】[FJOI2014]最短路径树问题

来源:互联网 发布:跳转页面js 编辑:程序博客网 时间:2024/06/01 08:00

! 卡时过了 为什么我的这么慢?姿势不对??? -->谢 ws_fqk 我的Do(num[i])应该用 DO(root) 找了半天的root居然没有用....
define的教训永远忘不了了!!!
优化了好几处才过的...者...

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#define MAXN 30010using namespace std;int n,m,k;bool b[MAXN];int team[10000000],head,tail,d[MAXN];int tot,g[MAXN],nnext[MAXN*2],num[MAXN*2],cost[MAXN*2];int tot0,g0[MAXN],nnext0[MAXN*4],num0[MAXN*4],cost0[MAXN*4];int tot1,g1[MAXN],nnext1[MAXN*4],num1[MAXN*4],cost1[MAXN*4];struct H{int x,y,z;}G[MAXN*4];bool cmp(H a,H b){if(a.x==b.x)return a.y>b.y;return a.x<b.x;}void SPFA(){    memset(d,61,sizeof(d));    d[1]=0;    team[++tail]=1;    while(head!=tail)    {        int x=team[++head];        b[x]=false;        for(int i=g0[x];i;i=nnext0[i])        {            int tmp=num0[i];            if(d[x]+cost0[i]<d[tmp])            {                d[tmp]=d[x]+cost0[i];                if(!b[tmp])                {                    b[tmp]=true;                    team[++tail]=tmp;                }            }        }    }}void Dfs_Road(int x){    b[x]=true;    for(int i=g1[x];i;i=nnext1[i])    {        int tmp=num1[i],z=cost1[i];        if(!b[tmp])        {            tot++,nnext[tot]=g[x],g[x]=tot,num[tot]=tmp,cost[tot]=z;            tot++,nnext[tot]=g[tmp],g[tmp]=tot,num[tot]=x;cost[tot]=z;            Dfs_Road(tmp);        }    }}//************点分治***************int root,sum,max_son[MAXN],size[MAXN],ans0,ans1,N[30000+1][2],T[30000+1][2];void Get_Root(int x,int fa){    size[x]=1;    max_son[x]=0;    for(int i=g[x];i;i=nnext[i])    if(num[i]!=fa&&!b[num[i]])    {        Get_Root(num[i],x);        max_son[x]=max(max_son[x],size[num[i]]);        size[x]+=size[num[i]];    }    max_son[x]=max(max_son[x],sum-size[x]);    if(max_son[x]<max_son[root]) root=x;}void Dfs_T(int x,int fa,int depth,int c){    if(depth>k) return;    if(c>T[depth][0]) T[depth][0]=c,T[depth][1]=1;    else if(c==T[depth][0]) T[depth][1]++;    for(int i=g[x];i;i=nnext[i])        if(!b[num[i]]&&num[i]!=fa)            Dfs_T(num[i],x,depth+1,c+cost[i]);}void Do(int x){    for(int i=0;i<=k;i++) N[i][0]=N[i][1]=0;    N[0][1]=1;    b[x]=true;    for(int i=g[x];i;i=nnext[i])    if(!b[num[i]])    {        for(int i=0;i<=k;i++) T[i][0]=T[i][1]=0;        Dfs_T(num[i],-1,1,cost[i]);        for(int i=1;i<=k;i++)        {            if(ans0<N[k-i][0]+T[i][0])                ans0=N[k-i][0]+T[i][0],ans1=N[k-i][1]*T[i][1];            else if(ans0==N[k-i][0]+T[i][0])                ans1+=N[k-i][1]*T[i][1];        }        for(int i=1;i<=k;i++)        {            if(N[i][0]<T[i][0])                N[i][0]=T[i][0],N[i][1]=T[i][1];            else if(N[i][0]==T[i][0])                N[i][1]+=T[i][1];        }    }    for(int i=g[x];i;i=nnext[i])    if(!b[num[i]])    {        root=0;sum=size[num[i]];        Get_Root(num[i],-1);        Do(root);    }}int main(){    cin>>n>>m>>k; k--;    for(int i=1;i<=m;i++)    {        int x,y,z;        scanf("%d %d %d",&x,&y,&z);        G[i]=(H){x,y,z};        G[i+m]=(H){y,x,z};        tot0++;nnext0[tot0]=g0[x],g0[x]=tot0,num0[tot0]=y;cost0[tot0]=z;        tot0++;nnext0[tot0]=g0[y],g0[y]=tot0,num0[tot0]=x,cost0[tot0]=z;    }    SPFA();     sort(G+1,G+m*2+1,cmp);    for(int i=1;i<=m*2;i++)    {        int x=G[i].x,y=G[i].y,z=G[i].z;        if(d[x]+z==d[y])            tot1++,nnext1[tot1]=g1[x],g1[x]=tot1,num1[tot1]=y,cost1[tot1]=z;    }        memset(b,false,sizeof(b));    Dfs_Road(1);    memset(b,false,sizeof(b));    root=0,sum=n,max_son[0]=n+1;    Get_Root(1,-1);    Do(root);    cout<<ans0<<' '<<ans1;    return 0;}
0 0
原创粉丝点击