8.19 T1
过不了大样例
查不出错。。。可能想错了
wawawa爆零了
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int N=500005;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
inline void Min(int &x,int y) {if(x>y)x=y;}
inline void Max(int &x,int y) {if(x<y)x=y;}
int jue(int x,int y) {return x>y?x-y:y-x;}
vector<int>v[N];
int n,k,fa[N],ban[N];
int to[N],nxt[N],hd[N],w[N],tot;
inline void add(int x,int y,int z) {
to[++tot]=y;w[tot]=z;nxt[tot]=hd[x];hd[x]=tot;
}
int dep[N],dis[N],mxdep;
int mi[N];
void dfs(int x) {
for(int i=hd[x];i;i=nxt[i]) {
int y=to[i];
if(y==fa[x]) continue;
dep[y]=dep[x]+1;
v[dep[y]].push_back(y);
Max(mxdep,dep[y]);
dis[y]=dis[x]+w[i];
Min(mi[dep[y]],dis[y]);
dfs(y);
}
}
int main() {
memset(mi,0x3f,sizeof(mi));
n=read();k=read();
for(int i=2,z;i<=n;i++) {
fa[i]=read();z=read();ban[i]=read();
add(fa[i],i,z);
}
dep[1]=0;mi[0]=0;
v[0].push_back(0);
dfs(1);
puts("0");
for(int s=1;s<=mxdep;s++) {
for(int j=0;j<v[s].size();j++) {
if(!ban[v[s][j]])
for(int last=0;last<=mxdep;last++)
Min(dis[v[s][j]],mi[last]+jue(s,last)*k);
Min(mi[s],dis[v[s][j]]);
}
}
for(int i=2;i<=n;i++)
printf("%d\n",dis[i]);
return 0;
}
不知所错。。。
去撸正解吧
额怎么说呢。。。想的又和正解挺像的
就是每层开vector 存一个当前层最小值
有一个点没有想到:
就是可以记录一个bestpos最优点,它后面的层都可以用它更新,正确性证明(口糊):
我们按层数从小到大推,设之前的bestpos为 i ,新的bestpos为 j (i到1的距离>j到1的距离) ,那么对后面的层 k 来说 dep[k]-dep[i] > dep[k]-dep[j] && i到1的距离>j到1的距离 ∴ 之后跳 j 一定比跳 i 优
还有个小优化 输入边权的时候如果能坐车就和k取min
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int N=500005;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
inline void Min(int &x,int y) {if(x>y)x=y;}
inline void Max(int &x,int y) {if(x<y)x=y;}
vector <int> v[N];
int n,k,fa[N],ban[N];
int to[N],nxt[N],hd[N],w[N],tot;
inline void add(int x,int y,int z) {
to[++tot]=y;w[tot]=z;nxt[tot]=hd[x];hd[x]=tot;
}
int dep[N],dis[N],mxdep;
int best[N],bestpos;
int get(int x,int y) {return best[x]+(y-x)*k;}
int main() {
memset(best,0x3f,sizeof(best));//每一层的最小值
n=read();k=read();
for(int i=2,z;i<=n;i++) {
fa[i]=read();z=read();ban[i]=read();
dep[i]=dep[fa[i]]+1;
Max(mxdep,dep[i]);
if(!ban[i]) Min(z,k);//优化
add(fa[i],i,z);
}
for(int i=1;i<=n;i++) v[dep[i]].push_back(i);
for(int i=0;i<=mxdep;i++) {//这个循环是第i层已经完成,在第i层推向第i+1层
for(int j=0;j<v[i].size();j++) {
int y=v[i][j];
Min(best[dep[y]],dis[y]);
}
int mi=best[i];
for(int j=0;j<v[i].size();j++)
if(!ban[v[i][j]])
Min(dis[v[i][j]],mi);
if(i&&get(bestpos,i)>get(i,i)) bestpos=i;
for(int j=0;j<v[i].size();j++) {
int x=v[i][j];
for(int s=hd[x];s;s=nxt[s]) {
int y=to[s];
dis[y]=dis[x]+w[s];
if(!ban[y]) Min(dis[y],get(bestpos,i+1));
}
}
}
for(int i=1;i<=n;i++)
printf("%d\n",dis[i]);
return 0;
}
/*
4 3
1 7 1
1 5 0
2 1 0
*/