BZOJ 4289 [PA2012]Tax

Link
is easy to think to tear down side, first split into undirected edges directed edges, then there is regarded as something new each graph to the side.
For the two artwork directed edge \ (E_1: A \ rightarrow B, E_2: B \ rightarrow C \) , we connected the new image directed edge \ (E_1 \ rightarrow E_2 \) , the right side of \ (\ max (W (E_1), W (E_2)) \) .
Then the \ (S \) to all the picture from \ (1 \) departing directed edge side even from the original to all \ (n-\) points to \ (T \) connected edge, right edge We are \ (0 \) .
Such artwork \ (1 \ rightarrow n \) is the shortest is the new image \ (s \ rightarrow t \) is the shortest.
It will be built directly into the side view of the card daisy \ (O (m ^ 2) \) .
Enumeration transit point in the original construction when edges \ (B \) and the difference can be done by Optimized FIG \ (O (m) \) .

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
namespace IO
{
    char ibuf[(1<<21)+1],*iS,*iT;
    char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
    int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
}
using IO::read;
using i64=long long;
const int N=500007,M=1500007;
int tot,head[N],ver[M],next[M],edge[M],vis[N];i64 dis[N];
struct pi{int x;i64 w;}a[N];
int operator<(pi a,pi b){return a.w>b.w;}
void add(int u,int v,int w){ver[++tot]=v,next[tot]=head[u],edge[tot]=w,head[u]=tot;}
int main()
{
    int n=read(),m=read(),c,s,t,d;memset(dis+n+1,0x7f,m<<4);
    for(int i=1,u,v,w;i<=m;++i) u=read(),v=read(),w=read(),add(u,v,w),add(v,u,w);
    for(int i=tot;i;i-=2) add(i+n-1,i+n,edge[i]),add(i+n,i+n-1,edge[i]);
    for(int u=1;u<=n;++u)
    {
    c=0;
    for(int i=head[u];i;i=next[i]) a[++c]={i+n,edge[i]};
    std::sort(a+1,a+c+1);
    for(int i=1;i<c;++i) add(a[i].x,a[i+1].x,0),add(a[i+1].x,a[i].x,a[i].w-a[i+1].w);
    if(u==1) s=a[c].x,d=a[c].w;
    if(u==n) t=a[c].x;
    }
    a[c=1]={s,dis[s]=d};
    for(int u;c;)
    {
    u=a[1].x,std::pop_heap(a+1,a+c+1),--c;if(vis[u])continue;vis[u]=1;
    for(int i=head[u],v;i;i=next[i]) if(dis[v=ver[i]]>dis[u]+edge[i]) a[++c]={v,dis[v]=dis[u]+edge[i]},std::push_heap(a+1,a+c+1);
    }
    printf("%lld",dis[t]);
}

Guess you like

Origin www.cnblogs.com/cjoierShiina-Mashiro/p/12233304.html