Silver Cow Party Currency Exchange
Silver Cow Party
题目
Silver Cow Party
德平在他的农场里养了n头牛,每头牛都有一个固定的位置,每天这些牛都要到德平家里参加聚会然后回去,给出n,m,代表牛数+1和有向边数,接着是m条有向边(a,b,c),代表从牛a到牛b需要花费c秒,给你德平家的位置X(1~n的除x外的编号为牛的位置),每头牛都有一个参加聚会并且回到原来位置的最短时间,从这些最短时间里找出一个最大值输出 N<=1000,M<=100,000,c<=100
Line 1: 三个整数分别代表: N, M, and X
Lines 2.. M+1: Line i+1 代表道路i的三个整数:a,b,c
表示从a到b需要c时间,(不能表示从b到a的时间为c)
Line 1: 所有 牛最短时间里找出一个 最大值输出
牛1:去4s,回1s,共5s
牛3:去6s,回3s,共9s
牛4:去3s,回7s,共10s
input
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
output
10
思路
有n个节点, 其中一个节点是要去到的终点x。
在除x之外的节点中, 找到一个节点, 它去到x点的最短距离 + 从x点回来的最短距离, 之和的最大值。
我们可以求出所有点到x和x到所有点的最短距离, 然后遍历一遍结果求出最大值。
dijkstra可以求出从起点开始到所有点的最短路径, 模板是求从起点到终点, 这里把x点当做起点即可求出x到所有点的距离。
至于所有点到x的距离, 可以将所有的有向边反转方向, 再求一次dijkstra便是所有点到x的最短距离。
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
//------- Coding Area ---------//
const int N = 1e3 + 10, INF = 0x3f3f3f3f;
int n, m, x;
int dist[N], g[N][N];
int d1[N], d2[N];
bool st[N];
void dijkstra()
{
memset(dist, INF, sizeof dist);
memset(st, 0, sizeof st);
dist[x] = 0;
for (int i = 1; i <= n; i++)
{
int t = -1;
for (int j = 1; j <= n; j++)
if (!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
st[t] = true;
for (int j = 1; j <= n; j++)
dist[j] = min(dist[j], dist[t] + g[t][j]);
}
}
int main()
{
cin.tie(0)->sync_with_stdio(false);
cin >> n >> m >> x;
memset(g, INF, sizeof g);
while (m--)
{
int a, b, c;
cin >> a >> b >> c;
g[a][b] = min(g[a][b], c);
}
// 第一次
dijkstra();
memcpy(d1, dist, sizeof dist);
for (int i = 1; i <= n; i++)
{
for (int j = i + 1; j <= n; j++)
swap(g[i][j], g[j][i]);
}
// 第二次
dijkstra();
memcpy(d2, dist, sizeof dist);
int res = 0;
for (int i = 1; i <= n; i++)
res = max(d1[i] + d2[i], res);
cout << res << endl;
return 0 ;
}
Currency Exchange
题目
太长就不贴了。
思路
大致是有没有一种情况, 币A 换到 币B, 然后币B换到币A, 最后总数比刚开始还多。
即 A->B 增加, B->A也增加, 显然是存在一个环路, 负环问题。正常的负环问题会导致最短最优路径为在环中循环, 使权值一直减少, 这里则是使权值一直增加。
计算两点之间的距离, 为 (上一点的币数 - 手续费) * 汇率
, 也就是(dist[t] - cost[i]) * rate[i]
。
代码
//#include "D:\Network_Computer_Scurity\Coding\OnlineJudgeProblem\Problems\Algorithm\aze.h"
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
//------- Coding Area ---------//
const int N = 1e3 + 111, M = N;
double v;
int n, m, s;
int h[N], e[M], ne[M], idx;
double dist[N], r[M], c[M]; // 汇率和手续
bool st[N];
int cnt[N];
bool spfa()
{
queue<int> q;
q.push(s);
dist[s] = v;
st[s] = true;
while (!q.empty())
{
int t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (dist[j] < (dist[t] - c[i]) * r[i])
{
dist[j] = (dist[t] - c[i]) * r[i];
cnt[j] = cnt[t] + 1;
if (cnt[j] >= n)
return true;
if (!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
return false;
}
void add(int a, int b, double R, double C)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx;
r[idx] = R, c[idx] = C;
idx++;
}
int main()
{
cin.tie(0)->sync_with_stdio(false);
cin >> n >> m >> s >> v;
memset(h, -1, sizeof h);
while (m--)
{
int a, b;
double ra, ca, rb, cb;
cin >> a >> b >> ra >> ca >> rb >> cb;
add(a, b, ra, ca);
add(b, a, rb, cb);
}
if (spfa())
cout << "YES\n";
else
cout << "NO\n";
return 0;
}