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 }
原文地址:https://www.cnblogs.com/ccd2333/p/6544934.html