POJ--3259--Wormholes【SPFA判负权值回路】

题意:有n个点,之间有m条双向路径,还有w个虫洞,单向,从一点到另一点需要花费时间,但是有虫洞的话会减少时间,一个人想要走某一条路使得他能碰到过去的自己,问这个图是否能让他实现他的想法。

其实就是判一个图是否存在负权值回路,SPFA可以实现,原理是:如果存在负权值回路,那么从源点到某个顶点的距离就可以无限缩短,因此就会无限入队,所以在SPFA中统计每个顶点的入队次数,如果超过了n个(顶点个数)则说明存在负权值回路。

我把输出yes和输出no写反了,WA了两发,看了半天都没发现。。。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 30100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct node{
    int u,v,next;
}edge[MAXN];
queue<int>q;
int dist[MAXN],head[MAXN],vis[MAXN],tot[MAXN];
int n,m,w,cnt,flag;
void add_edge(int a,int b,int c){
    edge[cnt].u = b;
    edge[cnt].v = c;
    edge[cnt].next = head[a];
    head[a] = cnt++;
}
void spfa(){
    int i,j;
    memset(vis,0,sizeof(vis));
    vis[1] = 1;
    for(i=1;i<=n;i++)   dist[i] = INF;
    dist[1] = 0;
    q.push(1);
    while(!q.empty()){
        int temp = q.front();
        q.pop();
        vis[temp] = 0;
        tot[temp]++;
        if(tot[temp]>n){
            flag = 1;
            break;
        }
        for(i=head[temp];i!=-1;i=edge[i].next){
            int jz = edge[i].v;
            if(jz+dist[temp]<dist[edge[i].u]){
                dist[edge[i].u] = jz + dist[temp];
                if(!vis[edge[i].u]){
                    vis[edge[i].u] = 1;
                    q.push(edge[i].u);
                }
            }
        }
    }
}
int main(){
    int t,i,a,b,c;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&w);
        memset(head,-1,sizeof(head));
        memset(tot,0,sizeof(tot));
        cnt = 0;
        flag = 0;
        while(!q.empty())   q.pop();
        for(i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            add_edge(a,b,c);
            add_edge(b,a,c);
        }
        for(i=0;i<w;i++){
            scanf("%d%d%d",&a,&b,&c);
            add_edge(a,b,-c);
        }
        spfa();
        if(flag)    puts("YES");
        else    puts("NO");
    }
    return 0;
}

POJ--3259--Wormholes【SPFA判负权值回路】,布布扣,bubuko.com

时间: 2024-08-24 20:49:41

POJ--3259--Wormholes【SPFA判负权值回路】的相关文章

POJ 3259 Wormholes(SPFA判负环)

题目链接:http://poj.org/problem?id=3259 题目大意是给你n个点,m条双向边,w条负权单向边.问你是否有负环(虫洞). 这个就是spfa判负环的模版题,中间的cnt数组就是记录这个点松弛进队的次数,次数超过点的个数的话,就说明存在负环使其不断松弛. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using na

POJ 3259 Wormholes (判负环)

Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 46123 Accepted: 17033 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path

POJ 3259 Wormholes 虫洞(负权最短路,负环)

题意:给一个混合图,求判断是否有负环的存在,若有,输出YES,否则NO.有重边. 思路:这是spfa的功能范围.一个点入队列超过n次就是有负环了.因为是混合图,所以当你跑一次spfa时发现没有负环,但是负环仍可能存在,因为有向边! 但是单源最短路也有起点啊,难道穷举起点?不用,负环是必须有某些边是带负权的,那么我们只要穷举负权边的起点就行了,因为单单跑一次spfa不能保证能遍历所有点,但是如果穷举负权边起点还没有找到负环,那么负环不可能存在(剩下的都是正权,怎么可能有负环). 1 //#incl

poj 3259 Wormholes[ bellman_ford 判负环]

Wormholes Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wor

POJ - 3259 Wormholes(求负权回路)

While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ's fa

POJ 3259 Wormholes( bellmanFord判负环)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36425   Accepted: 13320 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

poj 3259 wormholes AC代码(负权环判断, Bellmanford)

#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> #include<iomanip> #include<cstdlib> #include<cstdio> #include<vector> #include<algorithm> #include<cmath> #include<map> using namespa

poj 3259 Wormholes spfa : 双端队列优化 判负环 O(k*E)

1 /** 2 problem: http://poj.org/problem?id=3259 3 spfa判负环: 4 当有个点被松弛了n次,则这个点必定为负环中的一个点(n为点的个数) 5 spfa双端队列优化: 6 维护队列使其dist小的点优先处理 7 **/ 8 #include<stdio.h> 9 #include<deque> 10 #include<algorithm> 11 using namespace std; 12 13 class Graph

poj 3259 Wormholes 判断负权值回路

Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u   Java class name: Main [Submit] [Status] [Discuss] Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A w