关闭

POJ 3259 Wormholes (spfa判断负权环)

340人阅读 评论(0) 收藏 举报
分类:

题意:

给你一张图,图上有n个点,m条边,w个虫洞。
给你m条边的权值,再给你w个虫洞能回到过去的时间(也就是说是负权的意思)。
问你能不能找到一个环,环上的权值总和是负的。

思路:

spfa,即bellman-ford的队列优化。
我写的这个是用邻接矩阵存的图,时间上感觉不是特别有效率,然而此题并没有卡这些。

AC代码:

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>

using namespace std;

int dis[510];
int ma[510][510];
bool vis[510];// 是否在队列里
int cnt[510];

bool spfa(int n){
    queue<int> q;
    q.push(1);
    dis[1] = 0;
    cnt[1]++;
    int po;
    while(!q.empty()){
        po = q.front();
        q.pop();
        vis[po] = false;
        for(int i = 1;i <= n;i++){
            if(dis[i] > dis[po] + ma[po][i]){
                dis[i] = dis[po] + ma[po][i];
                if(vis[i] == false){
                    q.push(i);
                    vis[i] = true;
                    cnt[i]++;
                    if(cnt[i] >= n) return true; // 存在负权环
                }
            }
        }
    }
    return false;
}

int main()
{
    int t;
    cin>>t;
    int n,m,w;
    int x,y,z;
    while(t--){
        memset(ma,0x3f3f3f3f,sizeof(ma));
        memset(dis,0x3f3f3f3f,sizeof(dis));
        memset(vis,false,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        scanf("%d%d%d",&n,&m,&w);
        for(int i = 1;i <= m;i++){
            scanf("%d%d%d",&x,&y,&z);
            ma[x][y] = min(ma[x][y],z);
            ma[y][x] = min(ma[y][x],z);
        }
        for(int i = 1;i <= w;i++){
            scanf("%d%d%d",&x,&y,&z);
            ma[x][y] = min(ma[x][y],-z);
        }
        if(spfa(n))
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}
1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:18842次
    • 积分:2071
    • 等级:
    • 排名:第19056名
    • 原创:191篇
    • 转载:1篇
    • 译文:0篇
    • 评论:4条
    最新评论