其实很久之前做的了,但是怎么都不过,今天拿出来竟然改一下就过了= =||
大概就是 给了一张无向图,问从起点开始到每个点的次短路。首先我们dij处理处最短路径树,然后在这上面搞事情处理一下。枚举所有的非树边 设起点u终点v 则这条边可以更新所有LCA(u,v)到v的点的次短路,就是dis[u]+len+dis[v]-dis[i] 这个i是正在处理的点 dis表示到根的距离 但是每条非树边可以更新的点有点多,所以我们要树剖维护这个过程 ,就是更新 所有LCA(u,v)到v的点 然后你就挂了 不能带着lca! 不能带着lca! 不能带着lca! 就这个把我挂哭了
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
# define inf 0x3f3f3f3f
using namespace std;
const int maxn=100000+10;
struct node{int to,next,len,fr;bool o;}table[maxn<<2];
struct tree{int x,l,r;int mn,lazy;}t[maxn<<2];
int tot,head[maxn];
void add(int a,int b,int c){table[++tot]=(node){b,head[a],c,a};head[a]=tot;}
int n,m;
char s[1<<25];
inline long long read()
{
static char *c=s;
if(c==s) fread(c,1,1<<25,stdin);
long long u=0;
while(*c<48) ++c;
while(*c>32) u=u*10+*c++-48;
return u;
}
typedef pair<int,int>Pair;
priority_queue<Pair,vector<Pair>,greater<Pair> >Q;
int d[maxn],fr[maxn];
bool v[maxn];
void dij()
{
memset(d,0x3f,sizeof d);
d[1]=0; Q.push(make_pair(d[1],1));
while(!Q.empty())
{
Pair top=Q.top();
Q.pop();
int x=top.second;
if(v[x]) continue;
v[x]=1;
for(int i=head[x];i;i=table[i].next)
if(d[table[i].to]>d[x]+table[i].len)
{
d[table[i].to]=d[x]+table[i].len;
table[i].o=1;
table[fr[table[i].to]].o=0;
fr[table[i].to]=i;
Q.push(make_pair(d[table[i].to],table[i].to));
}
}
}
int f[maxn],dep[maxn],son[maxn],tp[maxn],w[maxn],pos[maxn],siz[maxn],cnt;
int ans[maxn][20];
void dfs1(int x)
{
dep[x]=dep[f[x]]+1;
siz[x]=1;
for(int i=1;i<=16;i++)
{
if(dep[x]<(1<<i)) break;
ans[x][i]=ans[ans[x][i-1]][i-1];
}
for(int i=head[x];i;i=table[i].next)
if(table[i].o&&table[i].to!=f[x])
{
f[table[i].to]=x;
ans[table[i].to][0]=x;
dfs1(table[i].to);
siz[x]+=siz[table[i].to];
if(siz[table[i].to]>siz[son[x]]) son[x]=table[i].to;
}
}
void dfs2(int x)
{
w[pos[x]=++cnt]=x;
if(x==son[f[x]]) tp[x]=tp[f[x]];
else tp[x]=x;
if(son[x]) dfs2(son[x]);
for(int i=head[x];i;i=table[i].next)
if(table[i].to!=son[x]&&table[i].o&&table[i].to!=f[x]) dfs2(table[i].to);
}
void maketree(int x,int l,int r)
{
t[x].l=l; t[x].r=r; t[x].lazy=t[x].mn=inf;
if(l==r) return ;
int mid=(t[x].l+t[x].r)>>1;
maketree(x<<1,l,mid);
maketree(x<<1|1,mid+1,r);
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int l=dep[x]-dep[y];
for(int i=0;i<=16;i++)
if(l&(1<<i)) x=ans[x][i];
for(int i=16;i>=0;i--)
if(ans[x][i]!=ans[y][i]) x=ans[x][i],y=ans[y][i];
return x==y?x:ans[x][0];
}
void pushdown(int x)
{
if(t[x].lazy==inf) return ;
int lc=x<<1,rc=x<<1|1;
t[lc].lazy=min(t[lc].lazy,t[x].lazy);
t[rc].lazy=min(t[rc].lazy,t[x].lazy);
t[lc].mn=min(t[lc].mn,t[x].lazy);
t[rc].mn=min(t[rc].mn,t[x].lazy);
}
void change(int x,int l,int r,int tar)
{
if(t[x].l==l&&t[x].r==r)
{
t[x].lazy=min(t[x].lazy,tar);
if(l==r) t[x].mn=min(t[x].mn,tar);
return ;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(r<=mid) change(x<<1,l,r,tar);
else if(l>mid) change(x<<1|1,l,r,tar);
else change(x<<1,l,mid,tar),change(x<<1|1,mid+1,r,tar);
}
void modify(int x,int lca,int tar)
{
int fx=tp[x];
while(dep[fx]>dep[lca])
{
change(1,pos[fx],pos[x],tar);
x=f[fx],fx=tp[x];
}
if(x!=lca) change(1,pos[lca]+1,pos[x],tar);
}
int search(int x,int pos)
{
if(t[x].l==t[x].r) return t[x].mn;
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(pos<=mid) return search(x<<1,pos);
else return search(x<<1|1,pos);
}
int main()
{
scanf("%d%d",&n,&m);
int a,b,c;
for(int i=1;i<=m;i++)
{
a=read(); b=read(); c=read();
add(a,b,c); add(b,a,c);
}
dij();
dfs1(1);
dfs2(1);
maketree(1,1,cnt);
for(int i=1;i<=tot;i++)
if(!table[i].o)
{
int t=LCA(table[i].fr,table[i].to);
modify(table[i].to,t,d[table[i].fr]+table[i].len+d[table[i].to]);
}
for(int i=2;i<=n;i++)
{
int x=search(1,pos[i]);
if(x==inf) puts("-1");
else printf("%d\n",x-d[i]);
}
return 0;
}