ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ 4289 [PA2012]Tax

2020-01-25 19:55:05  阅读:270  来源: 互联网

标签:原图 int Tax dis 4289 PA2012 tot include rightarrow


Link
很容易想到要拆边,先把无向边拆成有向边,再把每条有向边视作新图中的点。
对于原图中的两条有向边\(e_1:a\rightarrow b,e_2:b\rightarrow c\),我们在新图中连有向边\(e_1\rightarrow e_2\),边权为\(\max(w(e_1),w(e_2))\)。
然后从\(s\)到原图上所有从\(1\)出发的有向边连边,从原图上所有到\(n\)的点到\(t\)连边,边权都为\(0\)。
这样原图中\(1\rightarrow n\)的最短路就是新图中\(s\rightarrow t\)的最短路。
直接建边会被菊花图卡成\(O(m^2)\)。
建边时枚举原图中的中转点\(b\)然后差分优化建图可以做到\(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]);
}

标签:原图,int,Tax,dis,4289,PA2012,tot,include,rightarrow
来源: https://www.cnblogs.com/cjoierShiina-Mashiro/p/12233304.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有