题意:

给定一个带权有向图,若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)的更多相关文章

  1. 【BZOJ】1003: [ZJOI2006]物流运输trans(SPFA+DP)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1003 这题一开始看是不会的额,,,还是看题解了..一开始我觉得不能用最短路啥的,,看了题解发现这是d ...

  2. PAT 甲级 1087 All Roads Lead to Rome(SPFA+DP)

    题目链接 All Roads Lead to Rome 题目大意:求符合题意(三关键字)的最短路.并且算出路程最短的路径有几条. 思路:求最短路并不难,SPFA即可,关键是求总路程最短的路径条数. 我 ...

  3. 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 ...

  4. BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...

  5. BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1003 题意: 思路: 首先用spfa计算一下任意两天之内的最短路,dis[a][b]表示的就是在第a ...

  6. 51nod1326 遥远的旅途(spfa+dp)

    题意: 给出一个无向图,问从1到n是否存在一条长度为L的路径. n,m<=50,1<=路径长度<=10000,L<=10^18 思路: 改变一下思路,我们发现,假设从起点1走到 ...

  7. 2019.01.22 bzoj3875: [Ahoi2014&Jsoi2014]骑士游戏(spfa+dp)

    传送门 题意简述:nnn个怪物,对于编号为iii的怪物可以选择用aia_iai​代价将其分裂成另外的bib_ibi​个怪物或者用cic_ici​代价直接消灭它,现在问消灭编号为1的怪物用的最小代价. ...

  8. ACdreamOJ 1154 Lowbit Sum (数字dp)

    ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...

  9. 「SDOI2016」储能表(数位dp)

    「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...

随机推荐

  1. VFP 用 SPT 来发布一条 SELECT 到一个新的 SQL Server 表

    为了发布一条 SQL SELECT 语句来创建一个新的 SQL Server 表,  SQL Server 数据库的 select into/bulkcopy 选项必须是可用的. 在默认情况下, 对于 ...

  2. Spark SQL 之自定义删除外部表

    前言 Spark SQL 在删除外部表时,本不能删除外部表的数据的.本篇文章主要介绍如何修改Spark SQL 源码实现在删除外部表的时候,可以带额外选项来删除外部表的数据. 本文的环境是我一直使用的 ...

  3. Cesium案例解析(四)——3DModels模型加载

    目录 1. 概述 2. 代码 3. 解析 4. 参考 1. 概述 Cesium自带的3D Models示例,展示了如何加载glTF格式三维模型数据.glTF是为WebGL量身定制的数据格式,在网络环境 ...

  4. Mac-MacOS降级(Mac系统降级,系统回退)

    前言 最近把macOS更新到了 macOS Catalina,使用了一段时间后,结合自己的使用环境和体验,感觉 Catalina 不太好用,就想把系统回退到 macOS Mojave,但是平时几乎不用 ...

  5. IoU-aware Single-stage Object Detector for Accurate Localization

    网络的结构如下: 采用FPN结构,Backbone是RetinalNet,分成了P3~P7共5个Layer,分别训练不同尺寸的Box.每个Layer对应的Head有2个分支,包括一个单独的分支用来预测 ...

  6. Codeforces Round 450 D 隔板法+容斥

    题意: Count the number of distinct sequences a1, a2, ..., an (1 ≤ ai) consisting of positive integers ...

  7. 5.Python安装依赖(包)模块方法介绍

    1.前提条件 1). 确保已经安装需要的Python版本 2). 确保已经将Python的目录加入到环境变量中 2. Python安装包的几种常用方式 1). pip安装方式(正常在线安装) 2). ...

  8. POJ 2556 (判断线段相交 + 最短路)

    题目: 传送门 题意:在一个左小角坐标为(0, 0),右上角坐标为(10, 10)的房间里,有 n 堵墙,每堵墙都有两个门.每堵墙的输入方式为 x, y1, y2, y3, y4,x 是墙的横坐标,第 ...

  9. ArcGIS Engine开发碰到问题及解决方式

    1.问题描述——运行提示:ArcGIS version not specified. You must call RuntimeManager.Bind before creating any Arc ...

  10. python数据类型(第二弹)

    针对上一篇博文提出的若干种python数据类型,笔者将在本文和后续几篇博文中详细介绍. 本文着重介绍python数据类型中的整数型.浮点型.复数型.布尔型以及空值. 对于整数型.浮点型和复数型数据,它 ...