题目链接:https://nanti.jisuanke.com/t/31001

题目大意:给出一个含有n个点m条边的带权有向图,求1号顶点到n号顶点的最短路,可以使<=k条任意边的权值变为0。

样例输入 复制

1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2

样例输出 复制

3

解题思路:可以用两种做法,不过都差不多,应该算是同一种思路的不同写法。
第一种是在建图时,将一个点拆成k个层次的点,应该总共有k+1层,每个相同层次的点按输入的边权连接,每个点可以向它能连接到的点的下一个层次连接一条边权为0的边,这样你每使一条边权值变为0,即相当于走到了下一层图,永远不能走回,当走到第k+1层图时即不能使用了,在这个含有k+1层图的大图里跑下最短路就可以得出答案了
附上代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=;
const ll inf=0x3f3f3f3f;
struct qnode{
int u;
ll dis;
bool operator<(const qnode &a)const{
return dis>a.dis;
}
qnode(int a,ll b)
{
u=a;
dis=b;
}
};
struct node{
int v,w,next;
}edge[*maxn];
int n,m,k,tot=,head[maxn];
ll dis[maxn];
void add(int u,int v,int w)
{
edge[tot].v=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
void init()
{
tot=;
memset(head,-,sizeof(head));
}
void dij()
{
priority_queue<qnode> que;
memset(dis,inf,sizeof(dis));
dis[]=;
que.push(qnode(,));
while(!que.empty())
{
int u=que.top().u;
que.pop();
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v,w=edge[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
que.push(qnode(v,dis[v]));
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
for(int j=;j<=k;j++)
{
add(u+j*n,v+j*n,w); //同一层次的点用输入边权相连
if(j!=k)
add(u+j*n,v+(j+)*n,); //不同层次的点用0权值相连
}
}
if(k>=m)
{
printf("0\n");
continue;
}
ll ans=inf;
dij();
for(int i=;i<=k;i++)
ans=min(ans,dis[n+i*n]);
printf("%lld\n",ans);
}
return ;
}

第二种是用最短路+dp思想,再开一维数组记录已经使用了几次使边的权值为0,也是跑下最短路就可以了。

附上代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+;
const long long inf=0x3f3f3f3f;
struct node{
int v,w,next;
}edge[*maxn];
struct qnode{
int u,k;
long long dis;
bool operator<(const qnode &a)const{
return dis>a.dis;
}
qnode(int a,int b,long long c)
{
u=a;
k=b;
dis=c;
}
};
int n,m,k,tot=,head[maxn];
long long dis[maxn][];
void add(int u,int v,int w)
{
edge[tot].v=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
void init()
{
tot=;
memset(head,-,sizeof(head));
}
long long dijkstra()
{
priority_queue<qnode> que;
for(int i=;i<=n;i++)
{
for(int j=;j<=k;j++)
{
dis[i][j]=inf;
}
}
que.push(qnode(,,));
dis[][]=;
while(!que.empty())
{
int u=que.top().u,tempk=que.top().k;
if(u==n)
return dis[u][tempk];
que.pop();
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v,w=edge[i].w;
if(dis[u][tempk]+w<dis[v][tempk]) //同一层的最短路
{
dis[v][tempk]=dis[u][tempk]+w;
que.push(qnode(v,tempk,dis[v][tempk]));
}
if(tempk<k)
{
if(dis[u][tempk]<dis[v][tempk+]) //如果将这条边权值变为0,就会进入tempk+1层
{
dis[v][tempk+]=dis[u][tempk];
que.push(qnode(v,tempk+,dis[v][tempk+]));
}
}
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
init();
for(int i=;i<m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
printf("%lld\n",dijkstra());
}
return ;
}

ACM-ICPC 2018 南京赛区网络预赛 L题(分层最短路)的更多相关文章

  1. ACM-ICPC 2018 南京赛区网络预赛 L 【分层图最短路】

    <题目链接> 题目大意: 有N个城市,这些城市之间有M条有向边,每条边有权值,能够选择K条边 边权置为0,求1到N的最短距离. 解题分析: 分层图最短路模板题,将该图看成 K+1 层图,然 ...

  2. ACM-ICPC 2018 南京赛区网络预赛 L题(分层图,堆优化)

    题目链接: https://nanti.jisuanke.com/t/31001 超时代码: #include<bits/stdc++.h> using namespace std; # ...

  3. ACM-ICPC 2018 南京赛区网络预赛 E题

    ACM-ICPC 2018 南京赛区网络预赛 E题 题目链接: https://nanti.jisuanke.com/t/30994 Dlsj is competing in a contest wi ...

  4. ACM-ICPC 2018 南京赛区网络预赛 L. Magical Girl Haze

    262144K   There are NN cities in the country, and MM directional roads from uu to v(1\le u, v\le n)v ...

  5. ACM-ICPC 2018 焦作赛区网络预赛 L 题 Poor God Water

    God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...

  6. ACM-ICPC 2018 南京赛区网络预赛 L.Magical Girl Haze(分层最短路)

    There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a di ...

  7. 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, ...

  8. ACM-ICPC 2018 南京赛区网络预赛 - L Magical Girl Haze (分层迪杰斯特拉)

    题意:N个点,M条带权有向边,求可以免费K条边权值的情况下,从点1到点N的最短路. 分析:K<=10,用dist[i][j]表示从源点出发到点i,免费j条边的最小花费.在迪杰斯特拉的dfs过程中 ...

  9. ACM-ICPC 2018 南京赛区网络预赛 L && BZOJ 2763 分层最短路

    https://nanti.jisuanke.com/t/31001 题意 可以把k条边的权值变为0,求s到t的最短路 解析  分层最短路  我们建立k+1层图 层与层之间边权为0,i 向 i+1层转 ...

随机推荐

  1. 上传图片(photoClip)

    首先我们需要引入4个js包(这4个包总共106.6KB) <script src="__STATIC__/hammer.min.js" ></script> ...

  2. 手机移动端input date placehoder不显示

    要解决这个问题,我们可以伪造一个placehoder,通过css跟js来解决这个问题. 为什么要用js的原因是因为当你选择了时间之后,placehoder的文字没有清除掉,所以我们就需要把这个伪造的p ...

  3. Oracle 修改数据库表数据提交之后进行回滚

    --查看历史数据 select * from test1 as of timestamp to_timestamp('2018-12-23 14:41:00', 'yyyy-mm-dd hh24:mi ...

  4. CSS硬件加速的好与坏

    本文翻译自Ariya Hidayat的Hardware Accelerated CSS: The Nice vs The Naughty.感谢Kyle He帮助校对. 每个人都痴迷于60桢每秒的顺滑动 ...

  5. Codeforces 1154E Two Teams

    题目链接:http://codeforces.com/problemset/problem/1154/E 题目大意: 有n个队员,编号1~n,每个人的能力各自对应1~n中的一个数,每个人的能力都不相同 ...

  6. QTP 自动化测试桌面程序--笔记(关闭 启动程序脚本) 、安装

    0 安装qtp .exe 文件 安装 插件文件(如delph) 1 关闭 启动程序: 将要操作的程序-存入localdatatable中 设置 迭代一次 rem SystemUtil.ClosePro ...

  7. Java多线程之sleep方法阻塞线程-模拟时钟

    package org.study2.javabase.ThreadsDemo.status; import java.text.SimpleDateFormat; import java.util. ...

  8. HTTP协议 - 基础认识

    在http协议使用场景上我们最熟悉的可能就是浏览器了,作为本系列第一篇,就讲一个问题  ”浏览器怎么连接上服务器并获取网页内容的“ : 首先 浏览器怎么连接上服务器的? 如果对OSI七层模型或者TCP ...

  9. Jsoup的使用

    http://caidongrong.blog.163.com/blog/static/21424025220139292525874/

  10. How to create ISO on macOS

    hdiutil makehybrid -iso -joliet -o test1.iso /users/test/test1