poj3268 Silver Cow Party(两次SPFA || 两次Dijkstra)
题目链接
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)的更多相关文章
- poj3268 Silver Cow Party (SPFA求最短路)
其实还是从一个x点出发到所有点的最短路问题.来和回只需分别处理一下逆图和原图,两次SPFA就行了. #include<iostream> #include<cstdio> #i ...
- POJ3268 Silver Cow Party(dijkstra+矩阵转置)
Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15156 Accepted: 6843 ...
- POJ3268 Silver Cow Party —— 最短路
题目链接:http://poj.org/problem?id=3268 Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total ...
- 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 ...
- poj3268 Silver Cow Party(两次dijkstra)
https://vjudge.net/problem/POJ-3268 一开始floyd超时了.. 对正图定点求最短,对逆图定点求最短,得到任意点到定点的往返最短路. #include<iost ...
- POJ-3268 Silver Cow Party---正向+反向Dijkstra
题目链接: https://vjudge.net/problem/POJ-3268 题目大意: 有编号为1-N的牛,它们之间存在一些单向的路径.给定一头牛的编号X,其他牛要去拜访它并且拜访完之后要返回 ...
- POJ3268 Silver Cow Party Dijkstra最短路
Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to atten ...
- 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 ...
- 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 ...
随机推荐
- filebeat过滤
合并多行以[为头 multiline:pattern: '^\['negate: truematch: after ------------------------------------------ ...
- 算法习题-FFT
Q1(hdu1402): 给出两个很大的数字A,B,计算二者乘积. 分析:这个题目java应该能过,用FFT做能够加速计算.这里将字符串A按权(10进制)展开,前面的系数就是多项式的系数,这样就构造出 ...
- xpath定位中详解id 、starts-with、contains、text()和last() 的用法
1.XPATH使用方法 使用XPATH有如下几种方法定位元素(相比CSS选择器,方法稍微多一点): a.通过绝对路径定位元素(不推荐!) WebElement ele = driver.findEle ...
- WCF: Retry when service is in fault state.
Service Host: using System; using System.Configuration; using System.ServiceModel; using System.Serv ...
- python 日期时间处理
# 获取日期: import datetime #调用事件模块 today =datetime.date.today() #获取今天日期 deltadays =datetime.timedelta(d ...
- Nginx upstream的5种权重分配方式【转】
原文地址:Nginx upstream的5种权重分配方式 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight指定轮询几率,weig ...
- 新的玩具:Windows上的awesome
平铺式窗口管理器 基于xwindow(Linux/Unix采用的图形系统)有成千上百种窗口管理器.其中有一类窗口管理器很古怪,所有应用程序的窗口没有互相遮挡,而是平铺到屏幕上,这类窗口管理器叫 平铺式 ...
- 20155307 2016-2017-2 《Java程序设计》第七周学习总结
学号 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 认识Lambda语法,方法参考在重用现有API上扮演了重要角色,重用现有方法操作,可避免到处写下Lamb ...
- SearchSploit
在我们的GitHub上的Exploit Database存储库中包含一个名为"searchsploit"的Exploit-DB的命令行搜索工具,该工具还允许您在任何地方随身携带一个 ...
- SQL Server 将Id相同的字段合并,并且以逗号隔开
例如:有表MO_Cook,字段:FoodRoom,name 有如下数据: 要求:将FoodRoom中值相同的字段合并成一行,并将name的值用逗号隔开. 需要用到:STUFF函数. 查询语句如下: ...