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 }