ACM-ICPC 2018 南京赛区网络预赛 L题(分层最短路)
题目链接: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题(分层最短路)的更多相关文章
- ACM-ICPC 2018 南京赛区网络预赛 L 【分层图最短路】
<题目链接> 题目大意: 有N个城市,这些城市之间有M条有向边,每条边有权值,能够选择K条边 边权置为0,求1到N的最短距离. 解题分析: 分层图最短路模板题,将该图看成 K+1 层图,然 ...
- ACM-ICPC 2018 南京赛区网络预赛 L题(分层图,堆优化)
题目链接: https://nanti.jisuanke.com/t/31001 超时代码: #include<bits/stdc++.h> using namespace std; # ...
- ACM-ICPC 2018 南京赛区网络预赛 E题
ACM-ICPC 2018 南京赛区网络预赛 E题 题目链接: https://nanti.jisuanke.com/t/30994 Dlsj is competing in a contest wi ...
- 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 ...
- 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 ...
- 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 ...
- 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, ...
- ACM-ICPC 2018 南京赛区网络预赛 - L Magical Girl Haze (分层迪杰斯特拉)
题意:N个点,M条带权有向边,求可以免费K条边权值的情况下,从点1到点N的最短路. 分析:K<=10,用dist[i][j]表示从源点出发到点i,免费j条边的最小花费.在迪杰斯特拉的dfs过程中 ...
- ACM-ICPC 2018 南京赛区网络预赛 L && BZOJ 2763 分层最短路
https://nanti.jisuanke.com/t/31001 题意 可以把k条边的权值变为0,求s到t的最短路 解析 分层最短路 我们建立k+1层图 层与层之间边权为0,i 向 i+1层转 ...
随机推荐
- [转帖]oracle改版sql server问题点汇总
https://www.cnblogs.com/zhangdk/p/oracle_sqlserver.html 只记得 最开始的时候看过 没有具体的了解里面的特点 原作者总结的很好 留下来 以后说不定 ...
- 利用js给datalist或select动态添加option选项
<!DOCTYPE html> <html> <head> <title>鼠标点击时加载</title> <script type=& ...
- fatal: HttpRequestException encountered解决方法
最近在windows下git push提交就会弹出如下错误: 网上查了一下发现是Github 禁用了TLS v1.0 and v1.1,必须更新Windows的git凭证管理器,才行. https:/ ...
- C# Note16: wpf window 中添加enter和双击事件
一.添加回车(enter)事件 在C#编程时,有时希望通过按回车键,控件焦点就会自动从一个控件跳转到下一个控件进行操作. 以用户登录为例,当输入完用户名和密码后, 需要点击登录按钮,而登录按钮必须获 ...
- Dart语法基础
hello world // Define a function. printNumber(num aNumber) { print('The number is $aNumber.'); // Pr ...
- 前端开发之css
<!--页面中的组成部分通常随便打开一个网页,有文字,图片,视频,表格,音频,表单(注册信息) css 属性/尺寸/边框/背景 1.css的尺寸属性,就是大小width max-width mi ...
- Navicat软件安装
Navicat_10.1.7永久注册码 NAVH-WK6A-DMVK-DKW3
- DBX error:Driver could not be properly initialized .... 解决办法
系统: win7 64位+ MySql 将libmysql.dll和Dbxmys.dll 拷到 C:\Windows\SysWOW64 目录. ( 64位系统) 32位则拷到 c:\wind ...
- Lodop打印控件打印机可打区域的影响 设置纸张边缘为基点
由于打印机千差万别,打印开发也要注意针对客户各种打印机进行处理,Lodop提供了打印维护(PRINT_SETUP)可针对每个客户端进行微调,保存结果保存在客户端本地,对其他访问网站的客户没有影响. 由 ...
- ORACLE 增加两列字段
declare v_cnt number; V_SQL VARCHAR2 (500) := '';begin select count(*) into v_cnt from dual where ex ...