【GDOI2016Day2】第一题SigemaGO
来源:互联网 发布:朝鲜 知乎 编辑:程序博客网 时间:2024/05/22 00:34
题目大意
给出一个n个点m条边有向图。你可以添加最多lim条长度为L边,添加的边(x,y)必须满足存在一个z,使得原图中存在有向边(x,z)、(z,x)。求添加边后点1到n的最短路。
Data Constraint
n≤10000 m≤50000 lim≤5 所有边权和L均为正整数且≤1000
分析
n和lim都较小,所以可以尝试从这里入手。
如果把图分成lim+1层,那么可以用图的第i层(0≤i≤lim)表示添加了lim条边。
然后该如何从上一层跳到下一层呢?
枚举上述的z,然后枚举原图中连向z的边和z的出边。直接连接的复杂度较大,所以要对这个z开个新点z’,然后x向z’、z’向y连接一条边。这样复杂度只有O(m)
对每一层向下一层都这样连边,同一层的边则与原图相同。
然后从第0层的点1出发,跑一遍最短路即可(这里我打的时Dij+heap,数据没有卡spfa)。
时间复杂度为
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=110005,maxm=800005;int n,m,N,lim,tot,tt,L,h[maxn],e[maxm],next[maxm],dis[maxm],f[maxm],H[maxn],E[maxm],Next[maxm],id[maxn],pos[maxn];void add(int x,int y,int D){ e[++tot]=y; dis[tot]=D; next[tot]=h[x]; h[x]=tot;}void Add(int x,int y){ E[++tt]=y; Next[tt]=H[x]; H[x]=tt;}void up(int x){ if (x==1) { pos[id[1]]=1; return; } int fa=x/2; if (f[id[fa]]>f[id[x]]) { id[fa]^=id[x]^=id[fa]^=id[x]; up(fa); } pos[id[x]]=x;}void down(int x){ if (x*2>n) { pos[id[x]]=x; return; } int son=(x*2==n || f[id[x*2]]<=f[id[x*2+1]])?x*2:x*2+1; if (f[id[x]]>f[id[son]]) { id[x]^=id[son]^=id[x]^=id[son]; down(son); } pos[id[x]]=x;}int main(){ freopen("sigemago.in","r",stdin); freopen("sigemago.out","w",stdout); scanf("%d%d%d%d",&N,&m,&L,&lim); while (m--) { int x,y,D; scanf("%d%d%d",&x,&y,&D); Add(y,x); for (int i=0;i<=lim;i++) add(x+i*N,y+i*N,D); } n=(lim+1)*N; for (int i=1;i<=N;i++) { for (int k=0;k<lim;k++) { n++; for (int j=H[i];j;j=Next[j]) add(E[j]+k*N,n,L); for (int j=h[i];j;j=next[j]) if (e[j]<=(lim+1)*N)add(n,e[j]+(k+1)*N,0); //这个if绝对不能漏 } } memset(f,42,sizeof(f)); f[1]=0; for (int i=1;i<=n;i++) pos[i]=id[i]=i; while (n--) { int x=id[1]; id[1]=id[n+1]; pos[id[1]]=1; down(1); for (int i=h[x];i;i=next[i]) if (f[x]+dis[i]<f[e[i]]) { f[e[i]]=f[x]+dis[i]; up(pos[e[i]]); } } int ans=1e8; for (int i=0;i<=lim;i++) ans=min(ans,f[N+i*N]); if (ans==1e8) printf("-1\n");else printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0;}
0 0
- 【GDOI2016Day2】第一题SigemaGO
- 【GDOI 2016 Day2】第一题 SigemaGO
- 【GDOI 2016 Day2】第一题 SigemaGO
- 寄存 【GDOI 2016 Day2】第一题 SigemaGO
- 【JZOJ 4489】【GDOI 2016 Day2】第一题 SigemaGO
- 【GDOI 2016 Day2】SigemaGO
- {题解}[jzoj4489] GDOI2016 Day2_T1 SigemaGo
- GDOI 2016 Day2 T1 SigemaGO
- 第一题
- 第一题
- 第一题
- 第一题
- 第一题
- 第一题
- 第一题
- 第一题
- 第一题
- 第一题
- Swift 学习1
- Android 面试题
- 计算机科学与技术院校排名(2015,2016-2017)
- Host-Base LAN-Base LAN-Free Server-Free备份方式详解
- bat复制备份
- 【GDOI2016Day2】第一题SigemaGO
- javaIO流
- android开发笔记之多媒体—图片的颜色处理
- 使用bat对UiAutomator程序进行快速调试
- 如何简单形象又有趣地讲解神经网络是什么?
- XML_Java_ XML_利用Jdom(Java)解析xml文件 示例
- Unity3D之Easytouch控件控制主角移动
- 69道Spring面试题和答案
- Lock使用