和天梯中的直捣黄龙差不多。但是,通过这个问题,我对多参数最短路又有了更深一层的了解。

  这题因为点数比较多,所以如果直接用大力学长的在G上dfs找最短路径的条数的话,会TLE,所以需要剪枝。剪枝方法是,在dfs中当遇到dis>d[u]就直接return。具体见代码:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> pii;
const int N = + ; int n,m,st,ed;
int d[N],d2[N],val[N],pre[N];
struct edge
{
int v,w;
};
vector<edge> G[N]; void dij()
{
memset(pre,-,sizeof(pre));
memset(d,inf,sizeof(d));
memset(d2,,sizeof(d2));
d[]=;
d2[]=val[];
priority_queue<pii,vector<pii>,greater<pii> > Q;
Q.push(pii(,));
while(!Q.empty())
{
pii x = Q.top();Q.pop();
int u = x.second;
int dis = x.first;
if(d[u]<dis) continue;
for(int i=;i<G[u].size();i++)
{
edge& e = G[u][i];
if(d[e.v] >= d[u]+e.w)
{
if(d[e.v] > d[u]+e.w)
{
pre[e.v] = u;
d[e.v] = d[u]+e.w;
d2[e.v] = d2[u]+val[e.v];
Q.push(pii(d[e.v],e.v));
}
else
{
if(d2[e.v] < d2[u]+val[e.v])
{
pre[e.v] = u;
d2[e.v] = d2[u]+val[e.v];
Q.push(pii(d[e.v],e.v));
}
}
}
}
}
} int cnt = ;
bool vis[N];
void dfs(int u,int dis)
{
if(u==ed && dis==d[ed]) {cnt++;return;}
if(dis > d[ed]) return; // 剪枝!
for(int i=;i<G[u].size();i++)
{
edge& e = G[u][i];
if(!vis[e.v])
{
vis[e.v]=;
dfs(e.v,dis+e.w);
vis[e.v]=;
}
}
} void printAns(int now)
{
if(now != st) {printAns(pre[now]);printf(" ");}
printf("%d",now);
} int main()
{
while(scanf("%d%d%d%d",&n,&m,&st,&ed)==)
{
for(int i=;i<n;i++) {scanf("%d",val+i);G[i].clear();}
while(m--)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].push_back((edge){v,w});
G[v].push_back((edge){u,w});
}
dij(); cnt = ;memset(vis,,sizeof(vis));
dfs(st,); printf("%d %d\n",cnt,d2[ed]);
printAns(ed);
puts("");
}
}

  当然,用我自己之前的方法也是可以的:用set型的p数组记录来时的点,再反向dfs即可。具体见代码:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> pii;
const int N = + ; int n,m,st,ed;
int d[N],d2[N],val[N],pre[N];
set<int> p[N];
struct edge
{
int v,w;
};
vector<edge> G[N]; void dij()
{
memset(pre,-,sizeof(pre));
memset(d,inf,sizeof(d));
memset(d2,,sizeof(d2));
d[]=;
d2[]=val[];
priority_queue<pii,vector<pii>,greater<pii> > Q;
Q.push(pii(,));
while(!Q.empty())
{
pii x = Q.top();Q.pop();
int u = x.second;
int dis = x.first;
if(d[u]<dis) continue;
for(int i=;i<G[u].size();i++)
{
edge& e = G[u][i];
if(d[e.v] >= d[u]+e.w)
{
if(d[e.v] > d[u]+e.w)
{
p[e.v].clear();
p[e.v].insert(u); pre[e.v] = u;
d[e.v] = d[u]+e.w;
d2[e.v] = d2[u]+val[e.v];
Q.push(pii(d[e.v],e.v));
}
else
{
p[e.v].insert(u); if(d2[e.v] < d2[u]+val[e.v])
{
pre[e.v] = u;
d2[e.v] = d2[u]+val[e.v];
Q.push(pii(d[e.v],e.v));
}
}
}
}
}
} int cnt = ;
void dfs(int u)
{
if(u == st) {cnt++;return;}
for(set<int>::iterator it=p[u].begin();it!=p[u].end();it++)
{
int v = *it;
dfs(v);
}
} void printAns(int now)
{
if(now != st) {printAns(pre[now]);printf(" ");}
printf("%d",now);
} int main()
{
while(scanf("%d%d%d%d",&n,&m,&st,&ed)==)
{
for(int i=;i<n;i++) {scanf("%d",val+i);G[i].clear();}
while(m--)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].push_back((edge){v,w});
G[v].push_back((edge){u,w});
}
dij(); cnt = ;
dfs(ed); printf("%d %d\n",cnt,d2[ed]);
printAns(ed);
puts("");
}
}

  

  想说明一点的是,我的方法跑的比大力学长的跑的快了2ms:他的46,我的44。。233= =。

PAT L2-001 紧急救援 —— (多参数最短路)的更多相关文章

  1. PTA L2-001 紧急救援 (带权最短路)

    <题目链接> 题目大意: 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道 ...

  2. PTA L2-001 紧急救援-最短路(Dijkstra)多条最短路找最优解并输出路径 团体程序设计天梯赛-练习集

    L2-001 紧急救援 (25 分)   作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快 ...

  3. Task5.PyTorch实现L1,L2正则化以及Dropout

    1.了解知道Dropout原理 深度学习网路中,参数多,可能出现过拟合及费时问题.为了解决这一问题,通过实验,在2012年,Hinton在其论文<Improving neural network ...

  4. 修复FFMPEG 复用 PAT、PMT发送间隔小于25ms的错误

    目录 分析ffmpeg源码 分析问题 修改源码解决问题 分析ffmpeg源码 分析问题 mpegtsenc.c 找到发送PAT.PMT的函数 /* send SDT, PAT and PMT tabl ...

  5. 正则化,L1,L2

    机器学习中在为了减小loss时可能会带来模型容量增加,即参数增加的情况,这会导致模型在训练集上表现良好,在测试集上效果不好,也就是出现了过拟合现象.为了减小这种现象带来的影响,采用正则化.正则化,在减 ...

  6. 正则化项L1和L2

    本文从以下六个方面,详细阐述正则化L1和L2: 一. 正则化概述 二. 稀疏模型与特征选择 三. 正则化直观理解 四. 正则化参数选择 五. L1和L2正则化区别 六. 正则化问题讨论 一. 正则化概 ...

  7. 正则化项L1和L2的区别

    https://blog.csdn.net/jinping_shi/article/details/52433975 https://blog.csdn.net/zouxy09/article/det ...

  8. 机器学习(二十三)— L0、L1、L2正则化区别

    1.概念  L0正则化的值是模型参数中非零参数的个数. L1正则化表示各个参数绝对值之和. L2正则化标识各个参数的平方的和的开方值. 2.问题  1)实现参数的稀疏有什么好处吗? 一个好处是可以简化 ...

  9. 机器学习中正则化项L1和L2的直观理解

    正则化(Regularization) 概念 L0正则化的值是模型参数中非零参数的个数. L1正则化表示各个参数绝对值之和. L2正则化标识各个参数的平方的和的开方值. L0正则化 稀疏的参数可以防止 ...

随机推荐

  1. golang代码中生成pprof和trace报告

    // 生成 CPU 报告 import ( "context" "runtime/pprof" "log" ) func cpuProfil ...

  2. python 拟合曲线并求参

    需要对数据进行函数拟合,首先画一下二维散点图,目测一下大概的分布, 所谓正态分布,就是高斯分布,正态曲线是一种特殊的高斯曲线. python的scipy.optimize包里的curve_fit函数来 ...

  3. DSN 建立达梦7(DM)连接

    (DSN)Data Source Name 数据源名称 “ODBC数据源管理器”提供了三种DSN,分别为用户DSN.系统DSN和文件DSN.其中:      用户DSN会把相应的配置信息保存在Wind ...

  4. 一个SDL2.0程序的分析

    //把图片加载到SDL_Texture SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){       ...

  5. 【php设计模式】策略模式

    策略模式是针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能. <?php i ...

  6. 1 bootstrapValidator使用

    1 如何使用 引入 <link href="bootstrapValidator.min.css" rel="stylesheet"> css文件 ...

  7. MySQL cmd操作

    1.开启关闭服务 net start mysql net stio mysql 2.登陆 在CMD命令窗口敲入命令 mysql -hlocalhost -uroot -p 后按回车(注意这里的&quo ...

  8. Istio技术与实践05:如何用istio实现流量管理

    Istio是Google继Kubernetes之后的又一开源力作,主要参与的公司包括Google,IBM,Lyft等,它提供了完整的非侵入式的微服务治理解决方案,解决微服务的管理.网络连接以及安全管理 ...

  9. 3. caffe中 python Notebook

    caffe官网上的example中的例子,如果环境配对都能跑出来,接下来跑Notobook Example中的程序,都是python写的,这些程序会让你对如何使用caffe解决问题有个初步的了解(ht ...

  10. Java字节流read函数

    问题引入 做Java作业从标准输入流获取用户输入,用到了System.in.read(),然后出现了bug. //随机生成一个小写字母,用户猜5次,读取用户输入,并判断是否猜对 import java ...