题目链接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. [官网]CREATE EXTENSION PostGreSQL 创建函数的方法

    CREATE EXTENSION https://www.postgresql.org/docs/current/sql-createextension.html CREATE EXTENSION — ...

  2. Java8 Stream实例--统计出所有含‘张’字的人员的平均年龄

    package com.zhangxueliang.demo; import java.util.ArrayList; import java.util.List; import java.util. ...

  3. day 7-3 僵尸进程,孤儿进程与守护进程

    一.基本定义 正常情况下,子进程是通过父进程创建的,子进程在创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 进程完成它的工作终止之后,它 ...

  4. Day 4-2 random模块

    import random random.randint(1,100) # 从1到100中随机取出一个数.包含100 random.randrange(1,100) #功能和上面一样.只是不包含100 ...

  5. Flutter的输入框TextField

    TextFiled组件的API 先来看一下TextFiled的构造方法: const TextField({ Key key, this.controller, this.focusNode, thi ...

  6. Linux用户权限指令, 定时任务等指令

    一. 网卡配置详解 网络配置文件: /etc/sysconfig/network 网络接口配置文件: /etc/sysconfig/network-scripts/ifcfg-INTERFACE_NA ...

  7. How to blog on Github

    git clone https://github.com/test/test.github.io.git cd ~/test.github.io git config --global push.de ...

  8. CSS3之box-sizing属性

    box-sizing本身有三个属性:content-box(默认).border-box和padding-box. content-box:border与padding均不算入width中: bord ...

  9. endnote格式

    endnote插入参考文献后的对齐方式和缩进空格 听语音 | 浏览:4780 | 更新:2016-11-28 20:46 1 2 3 4 5 6 7 分步阅读 1.endnote 导入到word参考文 ...

  10. Go For It ,一个灵活的待办事项列表程序

    导读 Go For It,是我们开源工具系列中的第十个工具,它将使你在 2019 年更高效,它在 Todo.txt 系统的基础上构建,以帮助你完成更多工作. 每年年初似乎都有疯狂的冲动想提高工作效率. ...