POJ 3259 Wormholes (spfa判断负权环)

来源:互联网 发布:电商美工的目的 编辑:程序博客网 时间:2024/05/21 12:25

题意:

给你一张图,图上有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
原创粉丝点击