Codeforces667D(spfa+dp)
题意:
给定一个带权有向图,若P(A,B)表示节点A到B的最短路长度,选择四个节点ABCD,使得P(A,B)+P(B,C)+P(C,D)最大。
节点数n在1,000以内,边数m在2,000以内。
思路:
首先先将两两点之间的最短路都算出来。
之后建立pre和next两个数组,但在这里我用结构体保存其权值和编号一直算不出正确结果,退而求其次,只保存最长路径排名前三的结点,每次遇到一个更长的边,就将另外两条边往后推一个位置,给新的最长边留出位置。
在枚举的时候,当最长边不存在的时候、最长边对应的点与b、c点冲突的时候,两个最长边对应的点彼此冲突的时候,跳过此次枚举。
最后直接输出对应的结果编号即可。
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
const int inf = 99999999;
const int maxn = 10000 + 5;
struct edge {
int v, w;
};
int nex[maxn][3], pre[maxn][3];
vector<vector<edge>>a;
int n, m, dis[maxn][maxn];
bool flag[maxn][maxn];
void add_edge(int u, int v, int w) {
edge tmp;
tmp.v = v;
tmp.w = w;
a[u].push_back(tmp);
}
void spfa(int s) {
queue<int>q;
q.push(s);
dis[s][s] = 0; flag[s][s] = true;
while (!q.empty()) {
int u = q.front(); q.pop(); flag[s][u] = false;
for (int i = 0; i < a[u].size(); i++) {//扫描所有邻接点
if (dis[s][a[u][i].v] > dis[s][u] + a[u][i].w) {
dis[s][a[u][i].v] = dis[s][u] + a[u][i].w;
if (!flag[s][a[u][i].v]) {
q.push(a[u][i].v);
flag[s][a[u][i].v] = true;
}
}
}
}
}
void upd() {
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 3; j++) {
nex[i][j] = -1;
pre[i][j] = -1;
}
}
int i, j;
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
if (dis[i][j] == inf) continue;
if (nex[i][0] == -1 || dis[i][nex[i][0]]<dis[i][j]){
nex[i][2] = nex[i][1];
nex[i][1] = nex[i][0];
nex[i][0] = j;
}
else if (nex[i][1] == -1 || dis[i][nex[i][1]]<dis[i][j]){
nex[i][2] = nex[i][1];
nex[i][1] = j;
}
else if (nex[i][2] == -1 || dis[i][nex[i][2]]<dis[i][j]){
nex[i][2] = j;
}
}
}
for (i = 1; i <= n; i++){
for (j = 1; j <= n; j++){
if (dis[j][i] == inf) continue;
if (pre[i][0] == -1 || dis[pre[i][0]][i]<dis[j][i]){
pre[i][2] = pre[i][1];
pre[i][1] = pre[i][0];
pre[i][0] = j;
}
else if (pre[i][1] == -1 || dis[pre[i][1]][i]<dis[j][i]){
pre[i][2] = pre[i][1];
pre[i][1] = j;
}
else if (pre[i][2] == -1 || dis[pre[i][2]][i]<dis[j][i]){
pre[i][2] = j;
}
}
}
}
int main() {
int u, v, w;
scanf("%d%d", &n, &m);
a.resize(maxn);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dis[i][j] = inf;
flag[i][j] = false;
}
}
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
add_edge(u, v, w);
}
for (int i = 1; i <= n; i++) {
spfa(i);
}
upd();
int ans = 0, str[4];
for (int b = 1; b <= n; b++) {
for (int c = 1; c <= n; c++) {
if (b == c || dis[b][c] == inf) continue;
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
if (pre[b][k] == -1 || nex[c][l] == -1)continue;
if (pre[b][k] == b || pre[b][k] == c)continue;
if (nex[c][l] == b || nex[c][l] == c)continue;
if (pre[b][k] == nex[c][l])continue;
int tem = dis[pre[b][k]][b] + dis[b][c] + dis[c][nex[c][l]];
if (tem > ans)
{
ans = tem;
str[0] = pre[b][k]; str[3] = nex[c][l];
str[1] = b; str[2] = c;
}
}
}
}
}
printf("%d %d %d %d\n", str[0], str[1], str[2], str[3]);
return 0;
}
Codeforces667D(spfa+dp)的更多相关文章
- 【BZOJ】1003: [ZJOI2006]物流运输trans(SPFA+DP)
http://www.lydsy.com/JudgeOnline/problem.php?id=1003 这题一开始看是不会的额,,,还是看题解了..一开始我觉得不能用最短路啥的,,看了题解发现这是d ...
- PAT 甲级 1087 All Roads Lead to Rome(SPFA+DP)
题目链接 All Roads Lead to Rome 题目大意:求符合题意(三关键字)的最短路.并且算出路程最短的路径有几条. 思路:求最短路并不难,SPFA即可,关键是求总路程最短的路径条数. 我 ...
- HDU-3499:Flight(SPFA+dp)
Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to ...
- BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...
- BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1003 题意: 思路: 首先用spfa计算一下任意两天之内的最短路,dis[a][b]表示的就是在第a ...
- 51nod1326 遥远的旅途(spfa+dp)
题意: 给出一个无向图,问从1到n是否存在一条长度为L的路径. n,m<=50,1<=路径长度<=10000,L<=10^18 思路: 改变一下思路,我们发现,假设从起点1走到 ...
- 2019.01.22 bzoj3875: [Ahoi2014&Jsoi2014]骑士游戏(spfa+dp)
传送门 题意简述:nnn个怪物,对于编号为iii的怪物可以选择用aia_iai代价将其分裂成另外的bib_ibi个怪物或者用cic_ici代价直接消灭它,现在问消灭编号为1的怪物用的最小代价. ...
- ACdreamOJ 1154 Lowbit Sum (数字dp)
ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...
- 「SDOI2016」储能表(数位dp)
「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...
随机推荐
- VFP 用 SPT 来发布一条 SELECT 到一个新的 SQL Server 表
为了发布一条 SQL SELECT 语句来创建一个新的 SQL Server 表, SQL Server 数据库的 select into/bulkcopy 选项必须是可用的. 在默认情况下, 对于 ...
- Spark SQL 之自定义删除外部表
前言 Spark SQL 在删除外部表时,本不能删除外部表的数据的.本篇文章主要介绍如何修改Spark SQL 源码实现在删除外部表的时候,可以带额外选项来删除外部表的数据. 本文的环境是我一直使用的 ...
- Cesium案例解析(四)——3DModels模型加载
目录 1. 概述 2. 代码 3. 解析 4. 参考 1. 概述 Cesium自带的3D Models示例,展示了如何加载glTF格式三维模型数据.glTF是为WebGL量身定制的数据格式,在网络环境 ...
- Mac-MacOS降级(Mac系统降级,系统回退)
前言 最近把macOS更新到了 macOS Catalina,使用了一段时间后,结合自己的使用环境和体验,感觉 Catalina 不太好用,就想把系统回退到 macOS Mojave,但是平时几乎不用 ...
- IoU-aware Single-stage Object Detector for Accurate Localization
网络的结构如下: 采用FPN结构,Backbone是RetinalNet,分成了P3~P7共5个Layer,分别训练不同尺寸的Box.每个Layer对应的Head有2个分支,包括一个单独的分支用来预测 ...
- Codeforces Round 450 D 隔板法+容斥
题意: Count the number of distinct sequences a1, a2, ..., an (1 ≤ ai) consisting of positive integers ...
- 5.Python安装依赖(包)模块方法介绍
1.前提条件 1). 确保已经安装需要的Python版本 2). 确保已经将Python的目录加入到环境变量中 2. Python安装包的几种常用方式 1). pip安装方式(正常在线安装) 2). ...
- POJ 2556 (判断线段相交 + 最短路)
题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...
- ArcGIS Engine开发碰到问题及解决方式
1.问题描述——运行提示:ArcGIS version not specified. You must call RuntimeManager.Bind before creating any Arc ...
- python数据类型(第二弹)
针对上一篇博文提出的若干种python数据类型,笔者将在本文和后续几篇博文中详细介绍. 本文着重介绍python数据类型中的整数型.浮点型.复数型.布尔型以及空值. 对于整数型.浮点型和复数型数据,它 ...