题意:有分别来自 N 个农场的 N 头牛去农场 X 嗨皮,农场间由 M 条有向路径连接。每头牛来回都挑最短的路走,求它们走的路的最大长度?(注意来回走的路线可能不同,因为是单项图)
代码1:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 1024;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, cost;
Edge(){} //两个都是edge的构造函数
Edge(int to, int cost) : to(to), cost(cost){}
};
typedef pair<int, int> P; //优先队列会用到,first是路径长度,second是顶点号
vector<Edge> G[MAXN]; //图,这个是数组里面的元素是vector类型
int d[MAXN][MAXN]; //最短距离
int N, E; //N是顶点数,E是边数
void dijkstra(int s) //从顶点s到个个顶点的距离
{
priority_queue<P, vector<P>, greater<P> > que; //优先队列,按照first从小到大的顺序取值
d[s][s] = 0;
que.push(P(0, s));
while (!que.empty()) {
P p = que.top(); que.pop();
int v = p.second;
if (d[s][v] < p.first) {
continue;
}
Edge e;
for (int i = 0; i < G[v].size(); i++) {
e = G[v][i];
if (d[s][e.to] > d[s][v] + e.cost) {
d[s][e.to] = d[s][v] + e.cost;
que.push(P(d[s][e.to], e.to));
}
}
}
}
int main()
{
int M, X;
cin >> N >> M >> X;
X--;
int A, B, T;
while (M--) {
cin >> A >> B >> T;
A--; B--;
G[A].push_back(Edge(B, T));
}
memset(d, INF, sizeof(d));
for (int i = 0; i < N; i++) {
dijkstra(i);
}
int ans = 0;
for (int i = 0; i < N; i++) {
if (i == X) {
continue;
}
ans = max(ans, d[i][X] + d[X][i]); //要走完所有的点一定是最长的距离才能遍历完所有的点
} //因为得到的d数组存的就是每两个点的最短的距离了,如果想遍历完所有的点应该求最大的
cout << ans << endl;
return 0;
}
这是一般的解题思路,就是每个点都走一遍dijkstra之后在相加,还有一个简单的思路,就是正向图求一次dijkstra(当作去的时候的最短路径),反向图求一次dijstra(当作回来的时候的最短路径),再相加求出来回的最短路径。
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <functional>
#include <cstring>
using namespace std;
const int MAXN = 1024;
struct Edge {
int to, cost;
Edge(){}
Edge(int to, int cost) : to(to), cost(cost){}
};
typedef pair<int, int> P; //first最短距离,second顶点编号
vector<vector<Edge> > G(MAXN); //vector里面的元素是另一个vector,所以用()
vector<vector<Edge> > RG(MAXN);
//vector<Edge> G[MAXN];
//vector<Edge> RG[MAXN];
int d[MAXN]; //最短距离
int rd[MAXN];
int V, E;
void dijkstra(int s)
{
priority_queue<P, vector<P>, greater<P> > que;
memset(d, 0x3f, sizeof(d));
d[s] = 0;
que.push(P(0, s));
while (!que.empty()) {
P p = que.top(); que.pop();
int v = p.second;
if (d[v] < p.first) continue;
for (int i = 0; i < G[v].size(); i++) {
Edge e = G[v][i];
if (d[e.to] > d[v] + e.cost) {
d[e.to] = d[v] + e.cost;
que.push(P(d[e.to], e.to));
}
}
}
}
int main()
{
int M, X;
cin >> V >> M >> X;
--X;
while (M--) {
int a, b, t;
cin >> a >> b >> t;
--a; --b;
G[a].push_back(Edge(b, t));
RG[b].push_back(Edge(a, t));
}
// memset(d, 0x3f, sizeof(d));
dijkstra(X);
G = RG; //只有vector才可以这样赋值
// memcpy(G, RG, sizeof(RG));
memcpy(rd, d, sizeof(d)); //将d数组里面的元素复制给rd.
dijkstra(X);
for (int i = 0; i < V; i++) {
d[i] += rd[i];
}
cout << *max_element(d, d + V) << endl; //得到d数组里面最大一个值。
return 0;
}