题目链接:https://www.luogu.org/problem/P4568

不管是k条免费还是半价都可以做~~~

两种方法:

1.分层建图(但这种方法建图复杂度有点大)

就是几条免费建层图,每一层都有对应关系,层与层之间是也是对应关系但是价格免费

大概就是这么个意思,分层是常用的思路,k比较小才可以这样,不然会爆掉


//#pragma comment (linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#include<list>
#include<time.h>
#include<bitset>#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define lowbit(x) x&(-x)
#define min4(a, b, c, d) min(min(a,b),min(c,d))
#define min3(x, y, z) min(min(x,y),z)
#define max3(x, y, z) max(max(x,y),z)
#define max4(a, b, c, d) max(max(a,b),max(c,d))
#define pii make_pair
#define pr pair<int,int>
typedef unsigned long long ull;
typedef long long ll;
const int inff = 0x3f3f3f3f;
const long long inFF = 9223372036854775807;
const int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
const int mdir[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, -1, 1, 1, -1, -1, -1};
const double eps = 1e-10;
const double PI = acos(-1.0);
const double E = 2.718281828459;
using namespace std;
const int mod=1e9+7;
const int maxn=110005;
const int maxm=1200005;
int d[maxn];
int head[maxn],sign;
int n,m,k;
struct node
{int to,p,val;
}edge[maxm<<1];
void add(int u,int v,int val)
{edge[sign]=node{v,head[u],val};head[u]=sign++;
}
void addedge(int u,int v,int val)
{add(u,v,val),add(v,u,val);for(int i=1;i<=k;i++){add(u+i*n,v+i*n,val);add(v+i*n,u+i*n,val);add(u+(i-1)*n,v+i*n,0);add(v+(i-1)*n,u+i*n,0);}
}
void init()
{sign=0;memset(head,-1,sizeof(head));
}
void dij(int st)
{memset(d,0x3f,sizeof(d));d[st]=0;priority_queue<pr,vector<pr>,greater<pr> > q;q.push(pii(0,st));while(!q.empty()){pr now=q.top();q.pop();if(d[now.second]<now.first) continue;for(int i=head[now.second];~i;i=edge[i].p){int v=edge[i].to;if(d[v]>d[now.second]+edge[i].val){d[v]=d[now.second]+edge[i].val;q.push(pii(d[v],v));}}}
}
int main()
{int st,ed,x,y,val;scanf("%d %d %d",&n,&m,&k);init();scanf("%d %d",&st,&ed);for(int i=1;i<=m;i++){scanf("%d %d %d",&x,&y,&val);addedge(x,y,val);}for(int i=1;i<=k;i++)add(ed+(i-1)*n,ed+i*n,0);dij(st);printf("%d\n",d[ed+n*k]);return 0;
}

2.就是开二维数组dp

d[i][cnt]表示从st到i点用了cnt次免费的距离

每次松弛的时候判断一下u-v能不能用免费,能用免费d[v][cnt+1]=d[u][cnt]

不能用免费的话就是正常的判断 d[v][cnt]>d[u][cnt]+len(u,v) ?

思路就是这样,终于学了这个板子,我以为好难


//#pragma comment (linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#include<list>
#include<time.h>
#include<bitset>#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define lowbit(x) x&(-x)
#define min4(a, b, c, d) min(min(a,b),min(c,d))
#define min3(x, y, z) min(min(x,y),z)
#define max3(x, y, z) max(max(x,y),z)
#define max4(a, b, c, d) max(max(a,b),max(c,d))
#define pii make_pair
#define pr pair<int,int>
typedef unsigned long long ull;
typedef long long ll;
const int inff = 0x3f3f3f3f;
const long long inFF = 9223372036854775807;
const int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
const int mdir[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, 1, 1, -1, 1, 1, -1, -1, -1};
const double eps = 1e-10;
const double PI = acos(-1.0);
const double E = 2.718281828459;
using namespace std;
const int mod=1e9+7;
const int maxn=1e4+5;
const int maxm=1e5+5;
int d[maxn][11],vis[maxn][11];
int head[maxn],sign;
int n,m,k;
struct nod
{int u,val,t;bool friend operator<(nod s,nod e){return s.val>e.val;}
};
struct node
{int to,p,val;
}edge[maxm<<1];
void add(int u,int v,int  val)
{edge[sign]=node{v,head[u],val};head[u]=sign++;
}
void init()
{sign=0;for(int i=0;i<=n;i++) head[i]=-1;
}
int dij(int st,int ed)
{for(int i=0;i<=n;i++)for(int j=0;j<=k;j++)d[i][j]=inff,vis[i][0]=0;d[st][0]=0;priority_queue<nod> q;q.push(nod{st,0,0});while(!q.empty()){nod now=q.top();q.pop();int u=now.u,t=now.t;if(vis[u][t]) continue;vis[u][t]=1;if(u==ed) return d[u][t];for(int i=head[u];~i;i=edge[i].p){int v=edge[i].to;if(t<k&&d[v][t+1]>d[u][t]){d[v][t+1]=d[u][t];q.push(nod{v,d[v][t+1],t+1});}if(d[v][t]>d[u][t]+edge[i].val){d[v][t]=d[u][t]+edge[i].val;q.push(nod{v,d[v][t],t});}}}return -1;
}
int main()
{int st,ed,x,y,val;scanf("%d %d %d",&n,&m,&k);init();scanf("%d %d",&st,&ed);for(int i=1;i<=m;i++){scanf("%d %d %d",&x,&y,&val);add(x,y,val),add(y,x,val);}printf("%d\n",dij(st,ed));return 0;
}

洛谷P4568 飞行路线 最短路k条免费相关推荐

  1. 洛谷P4568 [JLOI2011] 飞行路线 题解

    洛谷P4568 [JLOI2011] 飞行路线 题解 题目链接:P4568 [JLOI2011] 飞行路线 题意: Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公 ...

  2. 洛谷 - P4568 [JLOI2011]飞行路线(分层图最短路)

    题目链接:点击查看 题目大意:给出一张图,每条边都有权值,现在要求从点st到达点ed,沿途中可以让k条边的边权免费,现在求最短路 题目分析:分层图经典模板问题,直接套板子就行了,最后记得对于数组d的每 ...

  3. 洛谷 P4568 [JLOI2011] 飞行路线(分层图最短路)

    [JLOI2011] 飞行路线 题目描述 Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在 n n n 个城市设有业务,设这些城市分别标记为 0 0 0 到 ...

  4. 洛谷P3357:最长k可重线段集问题(网络流)

    解析 本题的建模方法有很多,我的做法是补集思想转化成志愿者招募然后按照那道题的做法直接做,看题解更多是采用的对于不冲突的线段首尾加边的做法. 在前一道最长k可重区间问题中这两种做法谈不上孰优孰劣,但本 ...

  5. 【洛谷1144】最短路计数 最短路

    最短路计数 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶点数与边数. ...

  6. 【洛谷1527】 [国家集训队]矩阵乘法(整体二分)

    传送门 洛谷 Solution 考虑看到什么k小就整体二分套上去试一下. 矩形k小整体二分+二维树状数组就好了. 代码实现 // luogu-judger-enable-o2 /*mail: mlea ...

  7. 洛谷-P1428-小鱼比可爱

    小鱼比可爱 - 洛谷 解题思路: 1.第一条小鱼的左边是没有鱼的,所以没有不如他的,先输出0 2.从第二条鱼开始遍历,每一项都和他前面的比,如果当前的鱼的值比前面的大,那么计数器增加,循环结束,输出s ...

  8. 最短路分层图专题 洛谷P2939,4822,4568

    2020.6.3 今天主要练习了下分层图.看洛谷题解每次都能有新收获.今天本来想练dp,后来感觉可能会太自闭了,不如先来一发最短路,毕竟看家本领不能忘.然后点进了北京某年wc的一道题,让求1-n的最短 ...

  9. 洛谷2505 [HAOI2012]道路(最短路计数)

    洛谷传送门 [题目分析] 线段树?bczd,这么小的范围直接暴力就行啦. 直接O(n)枚举源点,每次跑最短路,然后对于每一条路径统计是否在最短路上.两个端点各有多少条最短路径经过即可. [代码~] # ...

最新文章

  1. luogu P5304 [GXOI/GZOI2019]旅行者
  2. mysql 技能进阶_mysql的高级进阶(一)
  3. 将SAP Analytics Cloud嵌入到SAP Cloud for Customer里去
  4. python从小白到大牛pdf 下载 资源共享_Kotlin从小白到大牛 (关东升著) 中文pdf高清版[12MB]...
  5. Android中的AutoCompleteTextView组件
  6. Nginx For Windows 关于 worker_connections 不生效问题
  7. 计组之总线:3、总线操作和定时(同步定时、异步定时、版同步通信、分离式通信)
  8. 中秋佳节--理解Enum枚举
  9. Linux常用50条命令
  10. html5 canvas图片反色
  11. origin 快捷键
  12. C++实现简单数独游戏
  13. OSChina 周四乱弹 ——程序员为啥要买苹果手机啊?
  14. 遇到的一个网页排版问题
  15. 酷柚易汛进销存-如何新增付款单?
  16. 为什么程序员容易猝死
  17. Reacte路由报错:A <Route> is only ever to be used as the child of <Routes> element, never rendered direct
  18. thingworx- 用户组
  19. sketch mac版设置快捷键的小技巧
  20. github Topic 功能 | github 常用条件查询

热门文章

  1. 微信小程序地图的实现
  2. MySQL 5.6中如何定位DDL被阻塞的问题
  3. 51NOD 1287 加农炮(不水的线段树)
  4. PHP的Reflection反射机制
  5. struts2笔记01-环境搭建
  6. 遍历Treeview每个节点并初始化(C#)
  7. 重大要素改变中的机会选择包括_财务人员专业胜任能力要素及框架
  8. axure动态登录和html5,Axure8原型设计实战案例:如何实现登录功能?
  9. 除了java还学什么_学好Java编程除了努力还需要具备什么?
  10. 商品详细信息的代码html_电商网站的商品详情页系统架构