bzoj2763 最短路

在我看来相当于拆点

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<queue>
 8 #define rep(i,l,r) for(int i=l;i<r;i++)
 9 #define clr(a,x) memset(a,x,sizeof(a))
10 using namespace std;
11 struct edge{
12     int to,v;
13 };
14 struct node{
15     int num,d,f;
16     bool operator <(const node&q)const{
17         return d>q.d;
18     }
19 };
20 const int maxn=10005,maxm=50005,maxk=15;
21 int n,m,k,s,t,d[maxn][maxk];
22 bool p[maxn][maxk];
23 priority_queue<node>q;
24 vector<edge>e[maxn];
25 int main()
26 {
27     clr(p,0);
28     node start,end;
29     start.d=0;
30     start.f=0;
31     cin>>n>>m>>k>>start.num>>end.num;
32     rep(i,0,n)
33         rep(j,0,k+1)
34             d[i][j]=10000000;
35      rep(i,0,k+1) d[start.num][i]=0;
36     rep(i,0,m){
37         edge ed;
38         int from;
39         scanf("%d%d%d",&from,&ed.to,&ed.v);
40         e[from].push_back(ed);
41         swap(from,ed.to);
42         e[from].push_back(ed);
43     }
44     q.push(start);
45     int cnt=0;
46     while(!q.empty()){
47         cnt++;
48         node now=q.top();
49         q.pop();
50         if(p[now.num][now.f]) continue;
51         p[now.num][now.f]=1;
52         p[now.num][now.f]=1;
53         rep(i,0,e[now.num].size()){
54             if(now.d+e[now.num][i].v<d[e[now.num][i].to][now.f]){
55                 d[e[now.num][i].to][now.f]=now.d+e[now.num][i].v;
56                 {
57                     node next;
58                     next.f=now.f;
59                     next.d=d[e[now.num][i].to][now.f];
60                     next.num=e[now.num][i].to;
61                     q.push(next);
62                 }
63             }
64             if(now.d<d[e[now.num][i].to][now.f+1]){
65                 d[e[now.num][i].to][now.f+1]=now.d;
66                 {
67                     node next;
68                     next.f=now.f+1;
69                     next.d=now.d;
70                     next.num=e[now.num][i].to;
71                     q.push(next);;
72                 }
73             }
74         }
75     }
76     printf("%d",d[end.num][k]);
77     return 0;
78 }

2763: [JLOI2011]飞行路线

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1075  Solved: 426
[Submit][Status][Discuss]

Description

Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

Input

数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。

第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)

接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)

Output

只有一行,包含一个整数,为最少花费。

Sample Input

5 6 1
0 4
0 1 5
1 2 5
2 3 5
3 4 5
2 3 3
0 2 100

Sample Output

8

HINT

对于30%的数据,2<=n<=50,1<=m<=300,k=0;

对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

Source

[Submit][Status][Discuss]

时间: 2024-10-22 12:28:00

bzoj2763 最短路的相关文章

BZOJ2763[JLOI2011]飞行路线 [分层图最短路]

2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2523  Solved: 946[Submit][Status][Discuss] Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Alice和Bob现在要从一个城市沿着航线到达另一个城市

bzoj2763:最短路

最短路,然后可以有多次免费的机会,不难写,但是最短路这次试着用指针写果然快了点,一开始看错数据范围数组开太大tle: ---------------------------------------------------------------------------------------------- #include<cstdio>#include<cstring>#include<queue>#include<iostream>#include<

BZOJ2763 JLOI2011 飞行路线 最短路

题意:给定一张图,有可以将K条路径的花费变为0,求从1到N的最短路 题解: 分层图+最短路水过. 我们把原图复制K份,平行的放在一起(就像饼干一样一层层的),然后给每个图编号1 2 3……K,然后对于原图中每一条边(x,y),在i的x和i+1的y之间连一条边权为0的边,然后在这K个图上做最短路即可. 当然这只是个思想,实际上你只需要多开一维记录在哪个层里即可,不用真的再去开N*(K-1)个点. #include <queue> #include <cstdio> #include

BZOJ2763, 最短路

好激动,没想到,我在这个网站AC的第一道是一个最短路的. 简单说一下吧!之所以开始做这道题还是想练一下最短路,因为刚重温了一下dijkstra.刚开始看到也是又蒙了,然后仔细一想,状态的转移应该不难,应该是分层进行的,不断地进行下一步决策.所以就把刘汝佳的dijkstra算法改了一下,用在这道题: 1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<vector> 5 #i

HDU5669 Road 分层最短路+线段树建图

分析:(官方题解) 首先考虑暴力,显然可以直接每次O(n^2) ?的连边,最后跑一次分层图最短路就行了. 然后我们考虑优化一下这个连边的过程 ,因为都是区间上的操作,所以能够很明显的想到利用线段树来维护整个图, 连边时候找到对应区间,把线段树的节点之间连边.这样可以大大缩减边的规模,然后再跑分层图最短路就可以了. 但是这样建图,每一次加边都要在O(logn)个线段树节点上加边,虽然跑的非常快,但是复杂度仍然是不科学的. 为了解决边的规模的问题,开两棵线段树,连边时候可以新建一个中间节点,在对应区

bzoj2763 飞行路线 二维SPFA

填坑填坑填坑--链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2763 题意:有$m$次免费机会,求出最小值. 二维最短路没什么说的.注意时间很坑人,要用双端队列优化$SPFA$(我再说一遍堆优化SPFA是不存在的--) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using na

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<