题目链接

http://poj.org/problem?id=3268

题意

有向图中有n个结点,编号1~n,输入终点编号x,求其他结点到x结点来回最短路长度的最大值。

思路

最短路问题,有1000个结点,Floyd算法应该会超时,我刚开始使用的Dijkstra算法也超时,原因是因为我使用一个循环遍历结点1~n,每次遍历我都使用两次Dijkstra求i到x和x到i的最短路,时间复杂度太高。降低时间复杂度的方法是先在原矩阵的基础上使用dijkstra求结点x到其余各点的最短路径,然后将矩阵转置,在转置矩阵的基础上使用dijkstra求结点x到其余各点的最短路径,这就相当于在原矩阵上求其余各点到x的最短路径,将两次得到的最短路径的值相加取最大值即可。这题也可以使用SPFA算法解决。

代码

SPFA算法:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std; struct Edge
{
int s, e, dist; Edge() {}
Edge(int s, int e, int d) :s(s), e(e), dist(d) {}
}; const int INF = 0x3f3f3f;
const int N = + ;
vector<Edge> v[N];
int dist[N];
int visit[N];
int n, m, x; int spfa(int s, int e) //返回从结点s到结点e的最短路
{
queue<int> q;
memset(visit, , sizeof(visit));
memset(dist, INF, sizeof(dist));
q.push(s);
visit[s] = ;
dist[s] = ; while (!q.empty())
{
int s = q.front();
q.pop();
visit[s] = ;
for (int i = ; i < v[s].size(); i++)
{
int e = v[s][i].e;
if (dist[e] > dist[s] + v[s][i].dist)
{
dist[e] = dist[s] + v[s][i].dist;
if (!visit[e])
{
visit[e] = ;
q.push(e);
}
}
}
}
return dist[e];
} int main()
{
//freopen("poj3268.txt", "r", stdin);
while (scanf("%d%d%d", &n, &m, &x) == )
{
int a, b, d;
for (int i = ; i < m; i++)
{
scanf("%d%d%d", &a, &b, &d);
v[a].push_back(Edge(a, b, d));
}
int ans = -;
for (int i = ; i <= n; i++)
{
if (i != x)
{
int dist1 = spfa(i, x);
int dist2 = spfa(x, i);
ans = max(ans, dist1 + dist2);
}
}
printf("%d\n", ans);
}
return ;
}

Dijkstra算法:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std; const int INF = 0x3f3f3f;
const int N = + ;
int map[N][N];
int dist[N], reverse_dist[N]; //记录x到其余各点的最短路径,和其余各点到x的最短路径
int visit[N];
int n, m, x; void dijkstra(int s)
{
memset(visit, , sizeof(visit));
for (int i = ; i <= n; i++)
dist[i] = map[s][i];
dist[s] = ;
visit[s] = ; int min_dist, now = s;
for (int i = ;i <= n; i++)
{
min_dist = INF;
for (int j = ; j <= n; j++)
{
if (!visit[j] && dist[j] < min_dist)
{
min_dist = dist[j];
now = j;
}
}
if (min_dist == INF) break;
visit[now] = ;
for (int j = ; j <= n; j++)
dist[j] = min(dist[j], dist[now] + map[now][j]);
}
} void reverse_map() //将原矩阵转置
{
for (int i = ;i <= n; i++)
{
for (int j = i + ; j <= n; j++)
{
int t = map[i][j];
map[i][j] = map[j][i];
map[j][i] = t;
}
}
} int main()
{
//freopen("poj3268.txt", "r", stdin);
while (scanf("%d%d%d", &n, &m, &x) == )
{
memset(map, INF, sizeof(map));
int a, b, d;
for (int i = ; i < m; i++)
{
scanf("%d%d%d", &a, &b, &d);
map[a][b] = d;
}
dijkstra(x);
for (int i = ; i <= n; i++)
reverse_dist[i] = dist[i];
reverse_map();
dijkstra(x);
int ans = -;
for (int i = ; i <= n; i++)
if (i != x)
ans = max(ans, dist[i] + reverse_dist[i]);
printf("%d\n", ans);
}
return ;
}

poj3268 Silver Cow Party(两次SPFA || 两次Dijkstra)的更多相关文章

  1. poj3268 Silver Cow Party (SPFA求最短路)

    其实还是从一个x点出发到所有点的最短路问题.来和回只需分别处理一下逆图和原图,两次SPFA就行了. #include<iostream> #include<cstdio> #i ...

  2. POJ3268 Silver Cow Party(dijkstra+矩阵转置)

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15156   Accepted: 6843 ...

  3. POJ3268 Silver Cow Party —— 最短路

    题目链接:http://poj.org/problem?id=3268 Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total ...

  4. POJ3268 Silver Cow Party (建反图跑两遍Dij)

    One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big co ...

  5. poj3268 Silver Cow Party(两次dijkstra)

    https://vjudge.net/problem/POJ-3268 一开始floyd超时了.. 对正图定点求最短,对逆图定点求最短,得到任意点到定点的往返最短路. #include<iost ...

  6. POJ-3268 Silver Cow Party---正向+反向Dijkstra

    题目链接: https://vjudge.net/problem/POJ-3268 题目大意: 有编号为1-N的牛,它们之间存在一些单向的路径.给定一头牛的编号X,其他牛要去拜访它并且拜访完之后要返回 ...

  7. POJ3268 Silver Cow Party Dijkstra最短路

    Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to atten ...

  8. poj3268 Silver Cow Party(农场派对)

    题目描述 原题来自:USACO 2007 Feb. Silver N(1≤N≤1000)N (1 \le N \le 1000)N(1≤N≤1000) 头牛要去参加一场在编号为 x(1≤x≤N)x(1 ...

  9. POJ3268 Silver Cow Party【最短路】

    One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big co ...

随机推荐

  1. 6 Easy Steps to Learn Naive Bayes Algorithm (with code in Python)

    6 Easy Steps to Learn Naive Bayes Algorithm (with code in Python) Introduction Here’s a situation yo ...

  2. 20155230 2016-2017-2《Java程序设计》第六周学习总结

    20155230 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象. 从应用程序角度 ...

  3. PHP面向对象__set(赋值方法)

    //类Ren里面的变量都是私有的,子类$r里面直接取是取不到的,正常给变量赋值的方法为$r->__set("age",20);,但是可以直接写成$r->age = 20 ...

  4. Python练习-函数(方法)的定义和应用

    需求:对文件进行增删改查,使用函数调用的方式完成操作 # 编辑者:闫龙 import MyFuncation; Menu = ["查询","添加"," ...

  5. Linux基础操作-分区概念

    开启Linux系统前添加一块大小为20G的SCSI硬盘 开启系统,右击桌面,打开终端 为新加的硬盘分区,一个主分区大小为10G,剩余空间给扩展分区,在扩展分区上划分两个逻辑分区,大小各5G 进入分区工 ...

  6. 【Loadrunner】LR参数化:利用mysql数据库里面的数据进行参数化

    很多同学都在自学loadrunner去做压力测试,但是如果要利用LR做压力测试,或者是其他工具,其中有一个环节是我们避开不了的,比如说:参数化 今天华华就给大家简要的介绍下,如果你要做的参数化的数据来 ...

  7. CSS line-height与行内框

    一.line-height的定义 line-height,行高,是指文本行基线间的垂直距离. 1.    什么是基线? 一般而言,一个文本行一共有四条线,从上到下依次为顶线.中线.基线.底线:在英文中 ...

  8. solr简介——(九)

    下载:     http://archive.apache.org/dist/lucene/solr/ 1.什么是solr Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lu ...

  9. 虚拟环境pipenv的使用

    安装虚拟环境 安装python3.6 python -m site --user-base 找到 用户基础目录 指定python版本的方式 pipenv --python 3.8 安装 用户范围内安装 ...

  10. iframe 同域下父子页面的通信

    //共同引用的JS文件 common.js ; (function (window, $) { $(function ($) { window.trip = window.trip || {}; wi ...