• bzoj 4016: [FJOI2014]最短路径树问题


    这题很显然直接最短路(蒟蒻只会spfa)搞出树,点分治就好,,然而不知道为什么不对。。(本机手动和AC代码对拍了一下没什么问题的样子。。。)

    挖坑++

      1 #include <bits/stdc++.h>
      2 #define LL long long
      3 #define inf 0x3f3f3f3f 
      4 #define N 30005
      5 using namespace std;
      6 inline int ra()
      7 {
      8     int x=0,f=1; char ch=getchar();
      9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     11     return x*f;
     12 }
     13 struct edge
     14 {
     15     int next,to,v;
     16 }e[N<<2];
     17 int head[N],cnt;
     18 int from[N],dis[N],val[N],q[N<<3];
     19 bool inq[N],vis[N],can[N];
     20 int n,m,k,mx_len,MAX,ans,root,sz;
     21 int depth[N];
     22 int size[N];
     23 map<int ,int > sum;
     24 void insert(int x, int y, int v)
     25 {
     26     e[++cnt].next=head[x]; e[cnt].to=y; e[cnt].v=v; head[x]=cnt;
     27 }
     28 void spfa()
     29 {
     30     for (int i=1; i<=n; i++) dis[i]=inf;
     31     int l=0,r=1; q[0]=1; dis[1]=0; inq[1]=1;
     32     while (l<r)
     33     {
     34         int x=q[l++]; 
     35         for (int i=head[x];i;i=e[i].next)
     36         {
     37             if (dis[e[i].to]==dis[x]+e[i].v && from[e[i].to]>x)
     38             {
     39                 from[e[i].to]=x;
     40                 val[e[i].to]=e[i].v;
     41             }
     42             if (dis[e[i].to]>dis[x]+e[i].v)
     43             {
     44                 dis[e[i].to]=dis[x]+e[i].v;
     45                 from[e[i].to]=x;
     46                 val[e[i].to]=e[i].v;
     47                 if (!inq[e[i].to])
     48                 {
     49                     inq[e[i].to]=1;
     50                     q[r++]=e[i].to;
     51                 }
     52             }
     53         }
     54         inq[x]=0;
     55     } 
     56 }
     57 void build_tree()
     58 {
     59     cnt=0; memset(head,0,sizeof(head));
     60     for (int i=1; i<=n; i++)
     61     {
     62         if (!vis[i])
     63         {
     64             while (i)
     65             {
     66                 if (vis[i]) break;
     67                 insert(from[i],i,val[i]);
     68                 insert(i,from[i],val[i]);
     69                 vis[i]=1;
     70                 i=from[i];
     71             }
     72         }
     73     }
     74 }
     75 void get_root(int x, int fa)
     76 {
     77     size[x]=1;
     78     int mx=0;
     79     for (int i=head[x];i;i=e[i].next)
     80     {
     81         if (can[e[i].to] || e[i].to==fa) continue;
     82         get_root(e[i].to,x);
     83         mx=max(mx,size[e[i].to]);
     84         size[x]+=size[e[i].to];
     85     }
     86     mx=max(mx,sz-size[x]);
     87     if (mx<MAX) MAX=mx,root=x;
     88 }
     89 void get_len(int x, int fa, int len, int deep)
     90 {
     91     mx_len=max(mx_len,depth[k-len]+deep);
     92     for (int i=head[x];i;i=e[i].next)
     93     {
     94         if (e[i].to==fa || can[e[i].to]) continue;
     95         get_len(e[i].to,x,len+1,deep+e[i].v);
     96     }
     97 }
     98 void add_len(int x, int fa, int len, int deep)
     99 {
    100     depth[len]=max(depth[len],deep);
    101     for (int i=head[x];i;i=e[i].next)
    102     {
    103         if (e[i].to==fa || can[e[i].to]) continue;
    104         add_len(e[i].to,x,len+1,deep+e[i].v);
    105     }
    106 }
    107 void clear_len(int x, int fa, int len)
    108 {
    109     depth[len]=0;
    110     for (int i=head[x];i;i=e[i].next)
    111     {
    112         if (e[i].to==fa || can[e[i].to]) continue;
    113         clear_len(e[i].to,x,len+1);
    114     }
    115 }
    116 void solve_len(int x)
    117 {
    118     MAX=n; sz=size[x]?size[x]:n; get_root(x,0); can[root]=1;
    119     for (int i=head[root];i;i=e[i].next)
    120     {
    121         if (can[e[i].to]) continue;
    122         get_len(e[i].to,root,1,e[i].v);
    123         add_len(e[i].to,root,1,e[i].v);
    124     }
    125     for (int i=head[root];i;i=e[i].next)
    126         if (!can[e[i].to]) clear_len(e[i].to,root,1);
    127     for (int i=head[root];i;i=e[i].next)
    128     {
    129         if (can[e[i].to]) continue;
    130         solve_len(e[i].to);
    131     }
    132 }
    133 void get_ans(int x, int fa, int deep)
    134 {
    135     ans+=sum[mx_len-deep];
    136 //    if (sum[mx_len-deep]){cout<<x<<"  "<<sum[mx_len-deep]; system("pause");}
    137     for (int i=head[x];i;i=e[i].next)
    138     {
    139         if (can[e[i].to] || e[i].to==fa) continue;
    140         get_ans(e[i].to,x,deep+e[i].v);
    141     }
    142 }
    143 void add_ans(int x, int fa, int deep)
    144 {
    145     sum[deep]++;
    146     for (int i=head[x];i;i=e[i].next)
    147     {
    148         if (fa==e[i].to || can[e[i].to]) continue;
    149         add_ans(e[i].to,x,deep+e[i].v);
    150     }
    151 }
    152 void clear_ans(int x, int fa, int deep)
    153 {
    154     sum[deep]=0;
    155     for (int i=head[x];i;i=e[i].next)
    156     {
    157         if (fa==e[i].to || can[e[i].to]) continue;
    158         clear_ans(e[i].to,x,deep+e[i].v);
    159     }
    160 }
    161 void final_solve(int x)
    162 {
    163     MAX=n; sz=size[x]?size[x]:n; 
    164     get_root(x,0); can[root]=1;
    165 //    cout<<root;system("pause");
    166     for (int i=head[root];i;i=e[i].next)
    167     {
    168         if (can[e[i].to]) continue;
    169         get_ans(e[i].to,root,e[i].v);
    170         add_ans(e[i].to,root,e[i].v);
    171     }
    172     for (int i=head[root];i;i=e[i].next)
    173         if (!can[e[i].to]) clear_ans(e[i].to,root,e[i].v);
    174     for (int i=head[root];i;i=e[i].next)
    175     {
    176         if (can[e[i].to]) continue;
    177         final_solve(e[i].to);
    178     }
    179 }    
    180 int main(int argc, char const *argv[])
    181 {
    182 //    freopen("bzoj4016.in","r",stdin);
    183     n=ra(); m=ra(); k=ra(); k--;
    184     for (int i=1; i<=m; i++) 
    185     {
    186         int x=ra(),y=ra(),v=ra();
    187         insert(x,y,v);
    188         insert(y,x,v);
    189     }
    190     spfa();
    191     build_tree();
    192     can[0]=1;    solve_len(1);
    193     memset(can,0,sizeof(can)); can[0]=1;
    194     memset(size,0,sizeof(size));
    195     final_solve(1);
    196     cout<<mx_len<<" "<<ans<<endl;
    197     return 0;
    198 }
  • 相关阅读:
    设置圆角代码
    队列组的简单使用
    多线程的延时执行和一次性代码
    GCD线程间的通信
    GCD"牛逼的中枢调度器"
    线程间的通信
    KVO运行时
    iOS Programming Localization 本地化
    iOS Programming State Restoration 状态存储
    如何安装sql server2005 windows 8
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6544934.html
Copyright © 2020-2023  润新知