首页 > 其他分享 >[JSOI2010]旅行

[JSOI2010]旅行

时间:2022-12-14 20:58:28浏览次数:62  
标签:JSOI2010 旅行 int edge edges 条边 data dp

链接:https://www.luogu.com.cn/problem/P6029 题目描述:给定一个$n$个$m$条边的无向图,可以交换$k$组边,求$1$到$n$的最短路。 题解:发现值域都比较小,考虑$dp$。 我们可以发现,存在一个段点$L$,使得前$L$条边只换不走,后面的$m-L$条边换为前$L$条边,这样走一定不会使答案更差。 令$dp_{i,j,k}$表示到节点$i$,在前$L$条边中选了$j$条边,轮换了$k$次的最短路。 则有: 当前边在前$L$条边时: $dp_{i,j,k}+edge_{j+1}->dp_{v,j+1,k}$ 当前边不在前$L$条边时: $dp_{i,j,k}+edge_{now}->dp_{v,j,k}$ $dp_{i,j,k}+edge_{j+1}->dp_{v,j,k+1}$ 转移可以建分层图跑最短路。 ``` #include #include #include using namespace std; struct node { int v,nxt,data; }; struct edg { int u,v,data; bool operator < (const edg &a)const { return data<a.data; }="" };="" struct="" reads="" {="" int="" num,data;="" bool="" operator="" <="" (const="" &a)const="" return="" data="">a.data; } }; node edge[2000001]; edg edges[1000001]; int n,m,k,head[1000001],dis[1000001],len; bool used[1000001]; void add(int x,int y,int z) { edge[++len].v=y; edge[len].data=z; edge[len].nxt=head[x]; head[x]=len; return; } int d(int x,int y,int z) { return (x-1)*(k+1)*(m+1)+y*(m+1)+z+1; } reads tmp; reads make_reads(int x,int y) { tmp.num=x; tmp.data=y; return tmp; } priority_queueq; void dijkstra() { int top; for (int i=1;i<=d(n,k,m);++i) { dis[i]=1e9; used[i]=0; } q.push(make_reads(1,0)); dis[1]=0; while (!q.empty()) { top=q.top().num; q.pop(); if (used[top]) continue; used[top]=1; for (int i=head[top];i>0;i=edge[i].nxt) if (dis[edge[i].v]>dis[top]+edge[i].data) { dis[edge[i].v]=dis[top]+edge[i].data; q.push(make_reads(edge[i].v,dis[edge[i].v])); } } return; } int main() { int x,y,ans=1e9; cin>>n>>m>>k; for (int i=1;i<=m;++i) cin>>edges[i].u>>edges[i].v>>edges[i].data; sort(edges+1,edges+m+1); for (int L=0;L<=m;++L) { len=0; for (int i=1;i<=d(n,k,m);++i) head[i]=0; for (int i=1;i<=m;++i) { for (int j=0;j<=k;++j) for (int t=0;t<=L;++t) { if (i<=L&&t+1<=L) { add(d(edges[i].u,j,t),d(edges[i].v,j,t+1),edges[t+1].data); add(d(edges[i].v,j,t),d(edges[i].u,j,t+1),edges[t+1].data); } else if (i>L) { add(d(edges[i].u,j,t),d(edges[i].v,j,t),edges[i].data); add(d(edges[i].v,j,t),d(edges[i].u,j,t),edges[i].data); } } for (int j=0;j<=k-1;++j) for (int t=0;t<=L-1;++t) if (i>L) { add(d(edges[i].u,j,t),d(edges[i].v,j+1,t+1),edges[t+1].data); add(d(edges[i].v,j,t),d(edges[i].u,j+1,t+1),edges[t+1].data); } } dijkstra(); for (int i=0;i<=k;++i) ans=min(ans,dis[d(n,i,L)]); } cout<

标签:JSOI2010,旅行,int,edge,edges,条边,data,dp
From: https://www.cnblogs.com/zhouhuanyi/p/16983495.html

相关文章

  • python奇妙旅行之4行代码生成图像验证码
    在学习的路上,永无止境。就好比人掉进"深渊",永远无法自拔!  ~ ~!我没有开车,我没有开车~~~今天空闲时间再看某大佬得论坛,被点了一下,就想起来了2种方法,生成图片验证码,简约......
  • 2022 最新海南岛旅行攻略 All In One
    2022最新海南岛旅行攻略AllInOne海南岛面积约3.54万平方公里,人口约940多万。人口GDPhttps://www.hainan.gov.cn/hainan/zfsj/xsj.shtmlhttps://www.hainan.......
  • 1088. 旅行问题
    题目链接1088.旅行问题John打算驾驶一辆汽车周游一个环形公路。公路上总共有\(n\)个车站,每站都有若干升汽油(有的站可能油量为零),每升油可以让汽车行驶一千米。John......
  • 旅行二
      ★实验任务王尼玛又想出去旅游了,由于王尼玛是个抠门的人,所以王尼玛想要花最少的钱去一个自己想去的地方。王尼玛决定使用火车去旅行,地图上总共有n个城市,其中有k个......
  • java最容易理解的旅行售货员问题
    packageNqueen;publicclasszuiduanluxian{/***旅行售货员问题--回溯法*@authorLican**/publicstaticclassBttsp{//建立一个javabean类而且是......
  • P4047 [JSOI2010]部落划分 题解
    最小生成树做法之Kruskal算法流程(详细分析请看代码注释):1.初始化并查集并查集模板不过多解释,还不懂请参阅并查集-OIWiki。每个节点的祖先最开始都是自己。还有......
  • P8855 [POI2002]商务旅行
    简要题意给出一个\(N\)个节点的树和一个长度为\(M\)的序列\(S\)。你需要从\(1\)出发,依次经过\(S\)中的所有点,求至少需要经过的边数。\(1\leN\le30000\)思......
  • 【路径规划】基于遗传算法求解固定的开放式多旅行推销员问题(M-TSP)附matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进。......
  • MFC-QT校园导航系统(旅行商TSP算法)
    MFC-QT校园导航系统(旅行商TSP算法)[问题描述]旅行商问题,给定若干城市和城市间距离,求解访问每一座城市一次并回到起始城市的最短回路。想象一个校园场景:某同学从宿舍出发......
  • P2134 百日旅行
    剩下n天的假期,小明可以安排旅行的计划。如果连续xx天旅游,小明需要花旅行费用p*x*x元;如果连续x天不旅游,小明吃饭,花费为q*x计算出他至少需要花费多少元。  需......