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\) 是否到达上界 ...
随机推荐
- 论文《learning to link with wikipedia》
learning to link with wikipedia 一.本文目标: 如何自动识别非结构化文本中提到的主题,并将其链接到适当的Wikipedia文章中进行解释. 二.主要借鉴论文: Miha ...
- Linux 发行版本简述
在撰写这篇文章前,先向linux创始人 Linus Torvalds 先生致敬,感谢您二十多年前的无私开源! 其次向二十多年来维护更新的开发者们致敬! Lin ...
- SAXParseException Content is not allowed in Prolog (前言中不允许有内容)
解析 XML 文件的时候,如 Mybatis 的 Mapper 文件,有时会出现 org.xml.sax.SAXParseException 前言中不允许有内容 的异常,英文就是 Content is ...
- Python面试(网编+数据库)
第一部分 必答题 简述 OSI 7层模型及其作用?(2分) 应用层:与用户直接交互,软件.网站等 表示层:使用软件.网站可以查看的数据,图片等 会话层:保持登录状态,电脑中为cookie 传输层:选择 ...
- splice和slice这两兄弟为毛这么难记
容易混淆,决定做下笔记!!! splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目. 语法 arrayObject.splice(index,howmany,item1,....., ...
- SAP SD 销售中的借贷项凭证
SAP SD 销售中的借贷项凭证 SAP系统中,正常与客户的应收款都能通过销售订单来实现. 但实际操作中,常有收款后发现价格有误或其他原因需退款客户或补收客户货款的情况,或者客户需要少量的材料,但不能 ...
- RequestFacade对象获取请求头时忽略大小写
也许在Controller层 在RequestFacde文件中getHeader函数逻辑实现如下所示: public String getHeader(String name) { if(this.r ...
- PHP0025:PHP 博客项目开发2
- VSCode 完美整合前后端框架(angular2+.NET core)
首先打开命令行查看本地.NET版本. 通过命令行安装模板. dotnet new --install Microsoft.AspNetCore.SpaTemplates::* 创建demo目录,并用v ...
- JS淘宝小广告
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...