BZOJ 3694 最短路

233333想简单了。。。。

题解参见http://hzwer.com/3710.html

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 4050
#define maxe 200500
#define inf 0x7f7f7f7f7f7f7f7fLL
using namespace std;
struct edge
{
long long u,v,w,flag,nxt;
}e[maxe];
long long n,m,x,y,a,b,g[maxv],nume=,dis[maxv];
long long top[maxv],fath[maxv],dfn[maxv],dep[maxv],size[maxv],son[maxv],times=;
long long root,tot=,ls[maxv<<],rs[maxv<<],lazy[maxv<<];
void addedge(long long u,long long v,long long w,long long flag)
{
e[++nume].u=u;
e[nume].v=v;
e[nume].w=w;
e[nume].flag=flag;
e[nume].nxt=g[u];
g[u]=nume;
}
void dfs1(long long x)
{
size[x]=;son[x]=;
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if ((e[i].flag) && (v!=fath[x]))
{
fath[v]=x;dep[v]=dep[x]+;dis[v]=dis[x]+e[i].w;
dfs1(v);
size[x]+=size[v];
if (size[v]>size[son[x]]) son[x]=v;
}
}
}
void dfs2(long long x,long long father)
{
dfn[x]=++times;top[x]=father;
if (son[x]) dfs2(son[x],father);
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if ((e[i].flag) && (v!=fath[x]) && (v!=son[x]))
dfs2(v,v);
}
}
void build(long long &now,long long left,long long right)
{
now=++tot;lazy[now]=inf;
if (left==right) return;
long long mid=(left+right)>>;
build(ls[now],left,mid);
build(rs[now],mid+,right);
}
void modify(long long now,long long left,long long right,long long l,long long r,long long x)
{
if ((left==l) && (right==r))
{
lazy[now]=min(lazy[now],x);
return;
}
long long mid=(left+right)>>;
if (r<=mid) modify(ls[now],left,mid,l,r,x);
else if (l>=mid+) modify(rs[now],mid+,right,l,r,x);
else {modify(ls[now],left,mid,l,mid,x);modify(rs[now],mid+,right,mid+,r,x);}
}
long long lca(long long u,long long v)
{
long long f1=top[u],f2=top[v];
while (f1!=f2)
{
if (dep[f1]<dep[f2]) {swap(f1,f2);swap(u,v);}
u=fath[f1];f1=top[u];
}
if (dep[u]<dep[v]) return u;
else return v;
}
void work(long long x)
{
long long u=e[x].u,v=e[x].v,ret=dis[u]+e[x].w+dis[v];
long long t=lca(u,v);
if (t==v) return;
u=t;
long long f1=top[u],f2=top[v];
while (f1!=f2)
{
if (dep[f1]<dep[f2]) {swap(f1,f2);swap(u,v);}
modify(root,,n,dfn[f1],dfn[u],ret);
u=fath[f1];f1=top[u];
}
if (u!=v)
{
if (dep[u]>dep[v]) swap(u,v);
modify(root,,n,dfn[u]+,dfn[v],ret);
}
}
long long ask(long long now,long long left,long long right,long long pos)
{
if (left==right)
return lazy[now];
long long mid=(left+right)>>;
if (pos<=mid) return min(ask(ls[now],left,mid,pos),lazy[now]);
else return min(ask(rs[now],mid+,right,pos),lazy[now]);
}
int main()
{
scanf("%lld%lld",&n,&m);
for (long long i=;i<=m;i++)
{
scanf("%lld%lld%lld%lld",&x,&y,&a,&b);
addedge(x,y,a,b);
addedge(y,x,a,b);
}
dfs1();
dfs2(,);
build(root,,n);
for (long long i=;i<=nume;i++)
{
long long u=e[i].u,v=e[i].v,ret=dis[u]+e[i].w+dis[v];
if (e[i].flag) continue;
work(i);
}
for (long long i=;i<=n;i++)
{
long long ret=ask(root,,n,dfn[i]);
if (ret==inf) printf("-1 ");
else printf("%lld ",ret-dis[i]);
}
printf("\n");
return ;
}
上一篇:C++排列对称串


下一篇:微信公众号开发C#系列-4、获取接口调用凭证