POJ-1860.CurrencyExchange(Spfa判断负环模版题)

时间:2023-03-09 13:38:43
POJ-1860.CurrencyExchange(Spfa判断负环模版题)

  本题思路:每完成一次交换之后交换余额多于原钱数则存在正环,输出YES即可。

参考代码:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std; const int maxn = 5e2;
struct node {
int to, next;
double r, c;
} G[maxn];
int n, m, s, num;
int head[maxn];
double v;
double dist[maxn];
bool vis[maxn]; void addedge(int u, int v, double r, double c) {
G[++num].to = v;
G[num].r = r;
G[num].c = c;
G[num].next = head[u];
head[u] = num;
} bool Spfa(int s, double v) {
queue <int> Q;
Q.push(s);
dist[s] = v;
while(!Q.empty()) {
int now = Q.front(); Q.pop();
vis[now] = false;
for(int k = head[now]; k; k = G[k].next) {
int next = G[k].to;
if(dist[next] < (dist[now] - G[k].c) * G[k].r) {
dist[next] = (dist[now] - G[k].c) * G[k].r;
if(!vis[next]) {
Q.push(next);
vis[next] = true;
}
}
}
if(dist[s] > v) return true;
}
return false;
} int main () {
scanf("%d %d %d %lf", &n, &m, &s, &v);
int a, b;
double r1, c1, r2, c2;
while(m --) {
scanf("%d %d %lf %lf %lf %lf", &a, &b, &r1, &c1, &r2, &c2);
addedge(a, b, r1, c1);
addedge(b, a, r2, c2);
}
if(Spfa(s, v)) printf("YES\n");
else printf("NO\n");
return ;
}

  之前还没有用过链式前向星这种建图方法,这里简述一下。其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.另外还有一个数组head[],它是用来

表示以i为起点的第一条边存储的位置。实际上你会发现这里的第一条边存储的位置其实在以i为起点的所有边的最后输入的那个编号。head[]数组一般初始化为-1,对于加边的add函数是这样的。初始化一个变量num为0来记录当前总共的边的个数。

  附一篇大佬的博客:博客链接

再附上我的邻接表建图的代码:这个较慢一点

 #include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; const int maxn = + ;
const double INF = 0x3f3f3f3f;
struct node {
int to;
double commission;
double rate;
};
vector<node> G[maxn];
double dist[maxn];
bool vis[maxn];
int n, m, s;
double v;
bool ans; bool spfa() {
memset(vis, false, sizeof vis);
for(int i = ; i <= n; i ++)
dist[i] = ;
dist[s] = v;
queue <int> Q;
Q.push(s);
while(!Q.empty()) {
int now = Q.front(); Q.pop();
for(int i = ; i < G[now].size(); i ++) {
node next = G[now][i];
if(dist[next.to] < (dist[now] - next.commission) * next.rate) {
dist[next.to] = (dist[now] - next.commission) * next.rate;
if(!vis[next.to]) Q.push(next.to);
}
}
if(dist[s] > v) return true;
}
return false;
} void addedge(int u, int v, double c, double r) {
G[u].push_back({v, c, r});
} int main () {
ios::sync_with_stdio(false);
int s1, s2;
double r1, c1, r2, c2;
ans = false;
cin >> n >> m >> s >> v;
for(int i = ; i < m; i ++) {
cin >> s1 >> s2 >> r1 >> c1 >> r2 >> c2;
addedge(s1, s2, c1, r1);
addedge(s2, s1, c2, r2);
}
ans = spfa();
if(ans) cout << "YES" << endl;
else cout << "NO" << endl;
return ;
}