poj3268 spfa 最短路
2016-11-19 10:40
162 查看
题目链接:点击打开链接
题意:
给定一个有向图;
问每头牛到固定地点聚会的花费加上回家的花费之和最大的花费是多少;
其中去和回都是最小的花费;
理解:
此题看上去可以先算回去的最小花费;
但是每头牛来的最小花费怎么算呢?
由于这个图是有向图;
如果把方向翻转了,那么去就是回,回就是去;
再算一次最短路就可以求出每头牛去和回的最短路之和了;
那么两次spfa就可以了;
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x7fffffff;
const int N = 10000000;
typedef pair<int, int> PII;
#define X first
#define Y second
const int MAXE = MAXN;
const int MAXV = 1011;
struct node {
int to, next, cost;
}e[MAXE];
int head[MAXV], tot;
int n, m;
void init() {
memset(head, -1, sizeof head);
tot = 0;
}
void add_edge(int u, int v, int cost) {
e[tot].to = v;
e[tot].next = head[u];
e[tot].cost = cost;
head[u] = tot++;
}
int dis[2][MAXV];
int outque[MAXV];
bool vis[MAXV];
bool spfa(int s, int t) {
for (int i = 1; i <= n; ++i) {
vis[i] = false;
dis[t][i] = INF;
outque[i] = 0;
}
queue<int> que;
que.push(s);
dis[t][s] = 0;
vis[s] = true;
while (!que.empty()) {
int u = que.front();
que.pop();
vis[u] = false;
if (++outque[u] > n) {
return false;
}
for (int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].to;
if (dis[t][v] <= dis[t][u] + e[i].cost) {
continue;
}
dis[t][v] = dis[t][u] + e[i].cost;
if (vis[v] == true) {
continue;
}
vis[v] = true;
que.push(v);
}
}
return true;
}
int edge[MAXV][MAXV];
int main() {
int x;
cin >> n >> m >> x;
memset(edge, -1, sizeof edge);
for (int i = 0; i < m; ++i) {
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
edge[u][v] = cost;
}
init();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (edge[i][j] != -1) {
add_edge(i, j, edge[i][j]);
}
}
}
spfa(x, 0);
init();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (edge[i][j] != -1) {
add_edge(j, i, edge[i][j]);
}
}
}
spfa(x, 1);
int ans = -1;
for (int i = 1; i <= n; ++i) {
ans = max(ans, dis[0][i] + dis[1][i]);
}
cout << ans << endl;
return 0;
}
题意:
给定一个有向图;
问每头牛到固定地点聚会的花费加上回家的花费之和最大的花费是多少;
其中去和回都是最小的花费;
理解:
此题看上去可以先算回去的最小花费;
但是每头牛来的最小花费怎么算呢?
由于这个图是有向图;
如果把方向翻转了,那么去就是回,回就是去;
再算一次最短路就可以求出每头牛去和回的最短路之和了;
那么两次spfa就可以了;
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 1e6 + 10;
const int MOD = 1e9 + 7;
const int INF = 0x7fffffff;
const int N = 10000000;
typedef pair<int, int> PII;
#define X first
#define Y second
const int MAXE = MAXN;
const int MAXV = 1011;
struct node {
int to, next, cost;
}e[MAXE];
int head[MAXV], tot;
int n, m;
void init() {
memset(head, -1, sizeof head);
tot = 0;
}
void add_edge(int u, int v, int cost) {
e[tot].to = v;
e[tot].next = head[u];
e[tot].cost = cost;
head[u] = tot++;
}
int dis[2][MAXV];
int outque[MAXV];
bool vis[MAXV];
bool spfa(int s, int t) {
for (int i = 1; i <= n; ++i) {
vis[i] = false;
dis[t][i] = INF;
outque[i] = 0;
}
queue<int> que;
que.push(s);
dis[t][s] = 0;
vis[s] = true;
while (!que.empty()) {
int u = que.front();
que.pop();
vis[u] = false;
if (++outque[u] > n) {
return false;
}
for (int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].to;
if (dis[t][v] <= dis[t][u] + e[i].cost) {
continue;
}
dis[t][v] = dis[t][u] + e[i].cost;
if (vis[v] == true) {
continue;
}
vis[v] = true;
que.push(v);
}
}
return true;
}
int edge[MAXV][MAXV];
int main() {
int x;
cin >> n >> m >> x;
memset(edge, -1, sizeof edge);
for (int i = 0; i < m; ++i) {
int u, v, cost;
scanf("%d%d%d", &u, &v, &cost);
edge[u][v] = cost;
}
init();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (edge[i][j] != -1) {
add_edge(i, j, edge[i][j]);
}
}
}
spfa(x, 0);
init();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (edge[i][j] != -1) {
add_edge(j, i, edge[i][j]);
}
}
}
spfa(x, 1);
int ans = -1;
for (int i = 1; i <= n; ++i) {
ans = max(ans, dis[0][i] + dis[1][i]);
}
cout << ans << endl;
return 0;
}
相关文章推荐
- poj3268 Silver Cow Party (SPFA求最短路)
- POJ3268 Silver Cow Party spfa求解 最短路
- hdu 0 or 1(最短路spfa)(本质,抽象)
- 暑假-最短路(Bellman-ford、spfa)-F - Wormholes
- HDOJ 2066 一个人的旅行(最短路之SPFA)
- 最短路【SPFA】算法模板
- hdoj 2544 最短路 【SPFA】
- poj3268最短路Dijkstrra
- TOJ 2217. Invitation Cards【最短路dijkstra+堆优化或者SPFA】
- HDU 2544 最短路(spfa邻接表)
- poj 2449Remmarguts' Date uvaoj 10740 not the best dijkstra或spfa或bellman-ford k短路 A*
- hdu2112 HDU Today (最短路之dijkstra和spfa)
- 【CodeVS】1269 匈牙利游戏 最短路 次短路 SPFA
- hdu2680(最短路spfa!此题有重大发现)
- 最短路练习10/poj/1511 Invitation Cards ,(两次spfa),(单源最短路,优先队列优化的Dijkstra)
- POJ_P1511 Invitation Cards(单源最短路+SPFA)
- 最短路 spfa, dijkstra, Floyd
- POJ2457 Part Acquisition(Spfa最短路+记录路径)
- POJ 2449 Remmarguts' Date(A*+SPFA)K短路问题
- G - MPI Maelstrom——最短路_spfa()算法