Wormholes

判断负圈的版子题

之前的题用Bellman法判断过了。
这里就用spfa判断一下负圈吧。

用spfa判断负圈的方法有两种:
1.记录节点入队的次数,若次数>n-1则有负圈
2.记录起点到节点经历的边数,若边数>n-1则有负圈(也可以理解为途经的节点数)

第二种会更快一点

代码如下:

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
const int max_n = 700;
const int max_m = 3000;
const int inf = 2e9;
struct edge{
    int to, cost, next;
}E[max_m << 1];
int head[max_n];
int cnt = 1;
void add(int from, int to, int cost) {
    E[cnt].to = to;E[cnt].cost = cost;
    E[cnt].next = head[from];head[from] = cnt++;
}

int d[max_n];
int cct[max_n];
bool vis[max_n];
bool spfa(int s,int n) {
    fill(d, d + max_n, inf);
    fill(cct, cct + max_n, 0);
    fill(vis, vis + max_n, false);
    queue<int> que;que.push(s);
    d[s] = 0;vis[s] = true;
    while (!que.empty()) {
        int u = que.front();
        que.pop();vis[u] = false;
        for (int i = head[u];i;i = E[i].next) {
            edge& e = E[i];
            if (d[e.to] > d[u] + e.cost) {
                d[e.to] = d[u] + e.cost;
                cct[e.to] = cct[u] + 1;
                if (cct[e.to] >= n)return true;
                if (vis[e.to])continue;
                vis[e.to] = true;
                que.push(e.to);
            }
        }
    }return false;
}

int N, M, W;
int main() {
    int tcase;scanf("%d", &tcase);
    while (tcase--) {
        fill(head, head + max_n, 0);cnt = 1;
        scanf("%d %d %d", &N, &M, &W);
        for (int i = 1, u, v, c;i <= M;++i) {
            scanf("%d %d %d", &u, &v, &c);
            add(u, v, c);add(v, u, c);
        }for (int i = 1, u, v, c;i <= W;++i) {
            scanf("%d %d %d", &u, &v, &c);
            add(u, v, -c);
        }spfa(1, N) ? printf("YES\n") : printf("NO\n");
    }
}

刷kuangbin大佬的题单,变强。。。。。。

全部评论

相关推荐

Lorn的意义:你这种岗位在中国现在要么牛马天天加班,要么关系户进去好吃好喝,8年时间,真的天翻地覆了,对于资本来说你就说一头体力更好的牛马,哎,退伍没有包分配你真的亏了。
点赞 评论 收藏
分享
绝迹的星:前端和后端写两份简历, 如果想干全栈就直接写求职意向为全栈工程师
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务