BZOJ 4289 [PA2012] Налоговая

Link
легко думать рушить сторону, первый раскол в неориентированных ребер , направленных ребер, то есть рассматривается как нечто новое для каждого графика в сторону.
Для двух художественных работ , направленный край \ (E_1: А \ RightArrow B, Е_2: В \ RightArrow С \) , мы подключили новое изображение направлено край \ (E_1 \ RightArrow Е_2 \) , правая сторона \ (\ макс (Вт (E_1), W (Е_2)) \) .
Тогда \ (S \) , чтобы все изображение с \ (1 \) отступая направленный боковой край даже от оригинала всем \ (п- \) указывает на \ (Т \) соединены край, правый край Мы \ (0 \) .
Такое произведение \ (1 \ RightArrow п \) является кратчайшим это новым образом \ (ы \ RightArrow т \) является самым коротким.
Он будет построен прямо на вид сбоку ромашке карты \ (O (м ^ 2) \) .
Перечень транзитный пункт в оригинальной конструкции , когда ребра \ (В \) , а разница может быть сделано путем Оптимизированная фиг \ (О (м) \) .

#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]);
}

рекомендация

отwww.cnblogs.com/cjoierShiina-Mashiro/p/12233304.html