分层图 (可以选择K条路的权为0,求最短路)
分层图可以处理从图中选取k条边使其边权变为0,求最短路
Description
    在你的强力援助下,PCY 成功完成了之前的所有任务,他觉得,现在正是出去浪的大好时光。于是,他来到高速公路上,找到一辆摩的前往几千公里以外他心仪的那家黄焖鸡米饭。
    由于 PCY 的品味异于常人,途经几百个城市的黄焖鸡米饭他都不屑一顾,他只愿意前往他心中最好的那家,但是为了一碗二十块钱的黄焖鸡米饭,他不愿意花上几千块的路费,他希望路费尽量少。高速路上的警察叔叔被他的行为所打动,于是在多方协调下,最多 K 条城市之间的高速收费站愿意免费为 PCY 放行(可以任意选择)。
    显然,PCY 已经筋疲力尽,不想再动用自己的数学天才来计算他可以花费的最小路费,因此他希望你可以帮他最后一次,他说他可以请你吃大碗的黄焖鸡米饭,还可以加一瓶豆奶。
    现在给你 N 个城市(编号为 0 … N - 1 ), M 条道路,和每条高速公路的花费 Wi ,以及题目所描述的 K。PCY 想从城市 S 到城市 T, 因为他对 T 城市的黄焖鸡米饭情有独钟。
Input (Prefix.in)
第一行,三个整数 N,M,K ,如题意所描述
第二行,两个整数 S,T ,代表出发城市和目标城市编号
接下来 M 行,每行三个整数 X,Y,W ,代表 X 和 Y 城市之间的高速公路收费为 W 元
Output (Prefix.out)
共一行,输出一个整数,代表 PCY 最少需要花费的路费。
借鉴Kigo的想法,分层图就是K层平行宇宙,每一层里有一个完整的图,但平行宇宙之间有互相连通的虫洞,可以从一个平行宇宙中的一个点瞬间到达下一个平行宇宙(原先x->y 边权为w,现在x->y’边权为0),然而虫洞是单向的,你不能回到上一个平行宇宙,只能向下一个平行宇宙走;最终,每一个平行宇宙都有同样的目的地,看到哪一个目的地最省钱
在这里,K层分层图说明最多有K条0边权的路可以走,建图后跑最短路即可
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXM 5000000
using namespace std; int s,t,n,m,k; inline int Read(){
int x=;char ch=getchar();
while(ch<'' || ch>''){ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x;
} struct E{
int next,to,v;
}edge[MAXM];
int head[MAXM];int edge_num;
int dis[MAXM]; void addedge(int x,int y,int z){
edge[++edge_num].next=head[x];
edge[edge_num].to=y;
edge[edge_num].v=z;
head[x]=edge_num;
} int que[MAXM];int front,tail;
bool inque[MAXM]; void PUSH(int x){
tail++;
if(tail==) tail=;
que[tail]=x;inque[x]=;
} int POP(){
front++;
if(front==) front=;
int t=que[front];
inque[t]=;
return t;
} void SPFA(int x){
memset(dis,0x7f,sizeof(dis));
PUSH(x);
dis[x]=;
while(front<tail){
int fro=POP();
int i;
for(i=head[fro];i;i=edge[i].next){
if(dis[edge[i].to]>dis[fro]+edge[i].v){
dis[edge[i].to]=dis[fro]+edge[i].v;
if(!inque[edge[i].to]){
PUSH(edge[i].to);
}
}
}
}
} void solve(){
SPFA(s);
int i;
int ans=0x7fffffff;
for(i=;i<=k;i++){
ans=min(ans,dis[t+n*i]);
}
printf("%d\n",ans);
} int main(){
freopen("Motor.in","r",stdin);
freopen("Motor.out","w",stdout);
n=Read();m=Read();k=Read();s=Read();t=Read();
int i;
if(k==){
for(i=;i<=m;i++){
int a=Read();int b=Read();int c=Read();
int j;
addedge(a,b,c);
addedge(b,a,c);
}
SPFA(s);
printf("%d\n",dis[t]);
return ;
}
for(i=;i<=m;i++){
int a=Read();int b=Read();int c=Read();
int j;
for(j=;j<=k;j++){
addedge(a+n*j,b+n*j,c);
addedge(b+n*j,a+n*j,c);
if(j<k){
addedge(a+n*j,b+n*(j+),);
addedge(b+n*j,a+n*(j+),);
}
}
}
solve();
return ;
}
不推荐
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ;
const int maxm = ;
const int inf = 0x3f3f3f3f; void Read(int& x)
{
char t = getchar();
while (t < '' || t > '') t = getchar();
x = ;
while (t >= '' && t <= '') {
x = x * + t - '';
t = getchar();
}
} struct Heap
{
int place[maxn], val[maxn], idx[maxn], node_cn; Heap() { node_cn = ; memset(place, , sizeof(place)); } inline void Swap(int x, int y)
{
swap(place[idx[x]], place[idx[y]]);
swap(val[x], val[y]);
swap(idx[x], idx[y]);
} void adjustup(int x)
{
while (x > ) {
if (val[x] < val[x >> ]) {
Swap(x, x >> );
x >>= ;
} else {
break;
}
}
} void adjustdown(int x)
{
int v;
while ((x << ) <= node_cn) {
v = x << ;
if (v + <= node_cn && val[v + ] < val[v]) v = v + ;
if (val[x] > val[v]) {
Swap(x, v);
x = v;
} else {
break;
}
}
} void insert(int id, int v)
{
if (place[id]) {
val[place[id]] = -inf;
adjustup(place[id]);
val[] = v;
adjustdown();
} else {
node_cn ++;
val[node_cn] = v, idx[node_cn] = id, place[id] = node_cn;
adjustup(node_cn);
} } void pop()
{
Swap(, node_cn);
node_cn --;
adjustdown();
}
}; int fst[maxn], edge_cn = ;
int u[maxm], v[maxm], w[maxm], nxt[maxm]; void addedge(int x, int y, int _w)
{
edge_cn ++;
u[edge_cn] = x, v[edge_cn] = y, w[edge_cn] = _w;
nxt[edge_cn] = fst[x];
fst[x] = edge_cn;
} int n, m, k, s, t;
int dis[maxn]; void input()
{
int x, y, z;
memset(fst, -, sizeof(fst));
Read(n), Read(m), Read(k);
Read(s), Read(t);
for (register int i = ; i <= m; i++) {
Read(x), Read(y), Read(z);
for (register int j = ; j <= k; j++) {
addedge(x + n * j, y + n * j, z);
addedge(y + n * j, x + n * j, z);
if (j < k) {
addedge(x + n * j, y + n * (j + ), );
addedge(y + n * j, x + n * (j + ), );
}
}
}
} Heap heap;
bool vis[maxn]; void Dijsktra()
{
int cn;
memset(dis, inf, sizeof(dis));
dis[s] = ;
heap.insert(s, );
while (heap.node_cn) {
cn = heap.idx[];
heap.pop();
if (vis[cn]) continue;
vis[cn] = true;
for (register int i = fst[cn]; i != -; i = nxt[i]) {
if (!vis[v[i]] && dis[v[i]] > dis[cn] + w[i]) {
dis[v[i]] = dis[cn] + w[i];
heap.insert(v[i], dis[v[i]]);
}
}
}
} void solve()
{
int ans = inf;
Dijsktra();
for (register int i = ; i <= k; i++) ans = min(ans, dis[t + i * n]);
printf("%d\n", ans);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("Motor.in", "r", stdin);
freopen("Motor.out", "w", stdout);
#endif input();
solve(); #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}
推荐:堆优化 , DJ
												
											分层图 (可以选择K条路的权为0,求最短路)的更多相关文章
- poj2455 k条路最小化最长边
		
Secret Milking Machine Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12414 Accepted ...
 - 2018icpc南京网络赛-L Magical Girl Haze (分层图最短路)
		
题意: 有向图,可以把k条路的长度变为0,求1到n的最短路 思路: 将图复制k份,一共k+1层图,对于每一条i→j,都连一条低层的i→高层的j,并且权值为0 即对每一对<i,j,w>,都加 ...
 - bzoj 2763: [JLOI2011]飞行路线  分层图
		
题目链接 n个点m条路, 每条路有权值, 给出起点和终点, 求一条路使得权值最小.可以使路过的路中, k条路的权值忽略. 其实就是多一维, 具体看代码 #include<bits/stdc++ ...
 - 2019牛客多校第四场J free——分层图&&最短路
		
题意 一张无向图,每条边有权值,可以选择不超过 $k$ 条路使其权值变成0,求 $S$ 到 $T$ 的最短路.(同洛谷 P4568) 分析 首先,分层图最短路可以有效解决这种带有 「阶段性」的最短路, ...
 - Codeforces Gym Joyride(分层图,dijkstra)
		
题意:有一张图,每条边有一个边权t表示经过所花时间,每个点有两个权t.p,分别表示经过该点所花时间和所花费用,要求找一条路径,从点1出发再回到点1,所花时间恰好为x且费用最小,输出其费用,找不到则输出 ...
 - ACM-ICPC 2018 南京赛区网络预赛 L 【分层图最短路】
		
<题目链接> 题目大意: 有N个城市,这些城市之间有M条有向边,每条边有权值,能够选择K条边 边权置为0,求1到N的最短距离. 解题分析: 分层图最短路模板题,将该图看成 K+1 层图,然 ...
 - bzoj2763: [JLOI2011]飞行路线(分层图spfa)
		
2763: [JLOI2011]飞行路线 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3234 Solved: 1235[Submit][Stat ...
 - poj 3613 经过k条边最短路 floyd+矩阵快速幂
		
http://poj.org/problem?id=3613 s->t上经过k条边的最短路 先把1000范围的点离散化到200中,然后使用最短路可以使用floyd,由于求的是经过k条路的最短路, ...
 - ACM-ICPC 2018 南京赛区网络预赛 L. Magical Girl Haze 最短路+分层图
		
类似题解 There are NN cities in the country, and MM directional roads from uu to v(1\le u, v\le n)v(1≤u, ...
 
随机推荐
- Java Modifiers
			
Private means this could only be seen within this class. Protected means "package private" ...
 - What is Photon Server?
			
http://blog.csdn.net/menuconfig/article/details/8215033 Photon Server是一套套裝的遊戲伺服器,以往開發線上遊戲都必需自行花費大筆的研 ...
 - redis安装及启动及设置
			
1. 安装 1.1 下载解压包,直接解压到任意路径下即可 windows下载地址:ttps://github.com/MSOpenTech/redis/releases 2.启动 2.1 启动要先开启 ...
 - HDOJ1171(多重背包)
			
#include<iostream> #include<cstdio> using namespace std; #define MAX(a,b) (a>b)?a:b + ...
 - @JsonProperty 注解
			
是Jackson注解.fastjson有可以用. 作用在字段或方法上,用来对属性的序列化/反序列化,可以用来避免遗漏属性,同时提供对属性名称重命名,比如在很多场景下Java对象的属性是按照规范的驼峰书 ...
 - 【转】Jquery折叠效果
			
转自:http://www.cnblogs.com/clc2008/archive/2011/10/25/2223254.html <!DOCTYPE html PUBLIC "-// ...
 - delphi 线程教学第二节:在线程时空中操作界面(UI)
			
第二节:在线程时空中操作界面(UI) 1.为什么要用 TThread ? TThread 基于操作系统的线程函数封装,隐藏了诸多繁琐的细节. 适合于大部分情况多线程任务的实现.这个理由足够了吧 ...
 - CSS之边距合并
			
外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者. 情况1:当一个元素出现在另一个元素上面时,第一个元素的下外边距与第二个元 ...
 - window下rails4.1 发生TZInfo::DataSourceNotFound 错误 - smallbottle
			
在官网上学习rails 4.1 ,启动rails server之后发生了如下错误 $ rails server Booting WEBrick Rails 4.1.0 application star ...
 - redis持久化  发布消息与订阅
			
vi /usr/local/redis/etc/redis.conf 快照方式: save 900 1 save 300 10 save 60 10000 aof方式: ap ...