题意:

给定一个带权有向图,若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. lwip的内存管理

    lwip可以不用malloc,而完全用pool,全用全局变量,没看明白怎么实现的. #if LWIP_NETCONN || LWIP_SOCKET LWIP_MEMPOOL(NETBUF, MEMP_ ...

  2. 卫星轨道相关笔记SGP4

    由卫星历书确定卫星轨道状态向量 卫星历书的表示方法有2种: TLE(Two Line Element),和轨道根数表示方法 由卫星历书计算出卫星轨道状态向量的方法有2种: SGP方法,NORAD的方法 ...

  3. hive执行计划简单分析

    原始SQL: select a2.ISSUE_CODE as ISSUE_CODE, a2.FZQDM as FZQDM, a2.FZQLB as FZQLB, a2.FJJDM as FJJDM, ...

  4. LVM 逻辑卷 (logica volume manager)

    逻辑卷轴管理员 (Logical Volume Manager) 想像一个情况,你在当初规划主机的时候将 /home 只给他 50G ,等到使用者众多之后导致这个 filesystem 不够大, 此时 ...

  5. Babel配置中的presets、plugins、各个阶段stage的含义

    什么是Babel Babel 官方文档: https://babeljs.io/ Babel 中文文档:https://www.babeljs.cn/ 我们知道各个浏览器对JavaScript版本的支 ...

  6. VS2015中使用qt开发客户端,QPluginLoader加载dll为null的解决办法

    1,问题重现: 使用vs2015开发一款qt软件,使用了QPluginLoader动态加载插件的方式,调试的时候,发现dll模块没有加载进来,debug发现QPluginLoader的instance ...

  7. DOTNET Core MVC(二)路由初探

    搁置了几天,工作忙的一塌糊涂,今天终于抽空来继续看看MVC的知识.先来看看MVC的路由是如何处理的.以下为替代的路由: app.UseEndpoints(endpoints => { endpo ...

  8. scrapy框架中多个spider,tiems,pipelines的使用及运行方法

    用scrapy只创建一个项目,创建多个spider,每个spider指定items,pipelines.启动爬虫时只写一个启动脚本就可以全部同时启动. 本文代码已上传至github,链接在文未. 一, ...

  9. MySQL面试笔试题集-BAT

    01.MySQL技术特点? Mysql数据库软件是一个客户端或服务器系统,支持各种客户端程序和库的多线程SQL服务器.不同的后端.广泛的应用程序编程接口和管理工具 02.MySQL默认端口号? 330 ...

  10. HTML连载67-手风琴效果、2D转换模块

    一.手风琴效果 <style> *{ margin:0; padding:0; } ul{ width: 960px; height: 300px; margin:100px auto; ...