POJ - 1860 题目链接
思路
一开始写到这个章节的时候不会写这道题,原因就是不知道spfa到底有什么用,因为一直听说spfa已死,这句话。
这是一道典型的spfa找负环的题,但是这里不同的是,这了的"负环"其实是正环。
稍加处理一下链式向前星,加入一个cost消耗量,接下来就是裸的spfa判断负环板子了
代码
//Powered by CK 2020:04:08
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N = 1e3 + 10;
int head[N], to[N], nex[N], cnt;
double rate[N], cost[N], dis[N], beg;
int visit[N], num[N], n, m, rt;
void add(int x, int y, double r, double c) {
to[cnt] = y;
nex[cnt] = head[x];
rate[cnt] = r;
cost[cnt] = c;
head[x] = cnt++;
}
bool spfa() {
memset(dis, 0, sizeof dis);
memset(visit, 0, sizeof visit);
memset(num, 0, sizeof num);
queue<int> q;
q.push(rt);
dis[rt] = beg;
visit[rt] = 1;
num[rt] = 1;
while(!q.empty()) {
int temp = q.front();
q.pop();
visit[temp] = 0;
for(int i = head[temp]; i; i = nex[i]) {
if(dis[to[i]] < (dis[temp] - cost[i]) * rate[i]) {
dis[to[i]] = (dis[temp] - cost[i]) * rate[i];
if(++num[to[i]] == n) return true;
if(!visit[to[i]]) {
visit[to[i]] = 1;
q.push(to[i]);
}
}
}
}
return dis[rt] > beg;
}
int main() {
// freopen("in.txt", "r", stdin);
int x, y;
double r, c;
while(scanf("%d %d %d %lf", &n, &m, &rt, & beg) != EOF) {
cnt = 1;
memset(head, 0, sizeof head);
for(int i = 0; i < m; i++) {
scanf("%d %d %lf %lf", &x, &y, &r, & c);
add(x, y, r, c);
scanf("%lf %lf", &r, &c);
add(y, x, r, c);
}
if(spfa()) puts("YES");
else puts("NO");
}
return 0;
}