ACM-ICPC 2018 南京赛区网络预赛__L. Magical Girl Haze 【Dijkstra算法+分层图思想】

本文主要是介绍ACM-ICPC 2018 南京赛区网络预赛__L. Magical Girl Haze 【Dijkstra算法+分层图思想】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  •  1000ms
  •  262144K

There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a distance ci​. Haze is a Magical Girl that lives in City 1, she can choose no more than K roads and make their distances become 0. Now she wants to go to City N, please help her calculate the minimum distance.

Input

The first line has one integer T(1≤T≤5), then following T cases.

For each test case, the first line has three integers N,M and K.

Then the following M lines each line has three integers, describe a road, Ui​,Vi​,Ci​. There might be multiple edges between u and v.

It is guaranteed that N≤100000,M≤200000,K≤10,
0 ≤Ci​≤1e9. There is at least one path between City 1 and City N.

Output

For each test case, print the minimum distance.

样例输入

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

样例输出

3

题目来源

ACM-ICPC 2018 南京赛区网络预赛

题目大意:有N个城市,M条有向边,城市之间可能有多条边,你可以选择让至多K条边的长度变为0,问最好的情况下,城市1到城市N的最短路径为多少

题解:Dijkstra算法+分层图思想,具体看代码来理解分层图思想

AC的C++代码:

#include<iostream>
#include<vector>
#include<queue>
#include<cstring> using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;
const int N=100003;struct Edge{//边 int v,w;//起点到终点v的花费为w Edge(int v,int w):v(v),w(w){} 
};struct Node{int u;int w;Node(){}Node(int u,int w):u(u),w(w){}bool operator<(const Node &a)const//使用优先队列,故将<重载为大于含义 {return w>a.w;}
};vector<Edge>g[N];
ll dist[N][11];//dist[i][j]表示在使得j条边为0的情况下源点到结点i的最短路 
bool vis[N][11];void dijkstra(int s,int n,int k)//源点为s,共有n个结点 可以选择k条边为0 
{priority_queue<Node>q;memset(vis,false,sizeof(vis));memset(dist,INF,sizeof(dist));dist[s][0]=0;q.push(Node(s,0));while(!q.empty()){Node e=q.top();q.pop();int z=e.u/(n+1);//z表示使z条边的长度为0 int u=e.u%(n+1);//u表示当前结点编号 if(!vis[u][z]){//如果还未用dist[u][z]更新其他状态就进行更新 vis[u][z]=true;int num=g[u].size();//与u相连的点有num个 for(int i=0;i<num;i++){int v=g[u][i].v;//v为与u相连的点if(vis[v][z])//如果dist[u][z]已经得到了就跳过 continue;int c=g[u][i].w;//c表示结点u到结点v的距离 //选择1:不让这条边为0if(dist[v][z]>dist[u][z]+c){ dist[v][z]=dist[u][z]+c;/*第一个参数 z*(n+1)+v是为了使得z可以通过e.u/(n+1)得到,u可以 通过e.u%(n+1)得到 */ q.push(Node(z*(n+1)+v,dist[v][z]));}if(z==k)//如果已经使k条边为0,就跳过 continue;//选择2:让这条边为0,则dist[v][z]变为dist[v][z+1]因为多让一条边变为0 if(dist[v][z+1]>dist[u][z]){ dist[v][z+1]=dist[u][z];q.push(Node((z+1)*(n+1)+v,dist[v][z+1]));}}}}
}int main()
{int t,n,m,a,b,k,c;scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&k);for(int i=0;i<=n;i++)g[i].clear();while(m--){scanf("%d%d%d",&a,&b,&c);g[a].push_back(Edge(b,c));}dijkstra(1,n,k);printf("%lld\n",dist[n][k]);}return 0;
} 

 

这篇关于ACM-ICPC 2018 南京赛区网络预赛__L. Magical Girl Haze 【Dijkstra算法+分层图思想】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626499

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

hdu1496(用hash思想统计数目)

作为一个刚学hash的孩子,感觉这道题目很不错,灵活的运用的数组的下标。 解题步骤:如果用常规方法解,那么时间复杂度为O(n^4),肯定会超时,然后参考了网上的解题方法,将等式分成两个部分,a*x1^2+b*x2^2和c*x3^2+d*x4^2, 各自作为数组的下标,如果两部分相加为0,则满足等式; 代码如下: #include<iostream>#include<algorithm

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问