君と ライフ

前速前进,Yoshiko!

POJ 3259 Wormholes (spfa判断负权环)

题意:

给你一张图,图上有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;
}
阅读更多
版权声明:本文为博主原(口)创(胡),未经博主允许不得转载,yosoro~ https://blog.csdn.net/wing_wuchen/article/details/52372773
上一篇hdu 2680 Choose the best route(spfa/dijkstra)
下一篇POJ 3013 Big Christmas Tree (最短路 spfa)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭