poj 3259 bellman最短路判断有无负权回路

Wormholes

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 36717   Accepted: 13438

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 wormhole! Each of FJ‘s farms
comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..N,
M (1 ≤ M ≤ 2500) paths, and W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to
F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input

Line 1: A single integer, F. F farm descriptions follow.

Line 1 of each farm: Three space-separated integers respectively: N,
M
, and W

Lines 2..M+1 of each farm: Three space-separated numbers (S,
E
, T) that describe, respectively: a bidirectional path between
S
and E that requires T seconds to traverse. Two fields might be connected by more than one path.

Lines M+2..M+W+1 of each farm: Three space-separated numbers (S,
E, T) that describe, respectively: A one way path from S to
E that also moves the traveler back T seconds.

Output

Lines 1..F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES

Hint

For farm 1, FJ cannot travel back in time.

For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.

Source

70ms

#include<iostream>  //79ms
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 10000000

using namespace std;

struct node
{
    int u,v,w;
} edge[5500];
int low[5500];
int n,m,z;
int num=0;
int Bellman()
{
    for(int i=0; i<=n; i++)
        low[i]=INF;

    for(int i=0; i<n-1; i++)
    {
        int flag=0;
        for(int j=0; j<num; j++)
        {
            if(low[edge[j].u]+edge[j].w<low[edge[j].v])
            {
                low[edge[j].v]=low[edge[j].u]+edge[j].w;
                flag=1;
            }
        }
        if(flag==0)  //存在负权回路
            break;
    }

    for(int j=0; j<num; j++)   //判断负权回路
    {
        if(low[edge[j].u]+edge[j].w<low[edge[j].v])
            return 1;
    }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&z);
        int a,b,c;
        num=0;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[num].u=a;
            edge[num].v=b;
            edge[num++].w=c;

            edge[num].u=b;
            edge[num].v=a;
            edge[num++].w=c;
        }

        for(int i=1; i<=z; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[num].u=a;
            edge[num].v=b;
            edge[num++].w=-c;
        }
        if(Bellman())
            printf("YES\n");
        else
            printf("NO\n");
    }
}

700ms

#include<iostream>  //挨个点遍历
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 0x3f3f3f3f

using namespace std;

struct node
{
    int u,v,w;
} edge[5500];
int low[550];
int n,m,z;
int num=0;
int Bellman(int u0)
{
    for(int i=0; i<=n; i++)
        low[i]=INF;
    low[u0]=0;
    for(int i=0; i<n; i++)  //递推n次,让其构成环来判断
    {
        int flag=0;
        for(int j=0; j<num; j++)
        {
            if(low[edge[j].u]!=INF&&low[edge[j].u]+edge[j].w<low[edge[j].v])
            {
                low[edge[j].v]=low[edge[j].u]+edge[j].w;
                flag=1;
            }
        }
        if(flag==0)  //存在负权回路(减少时间)
            break;
    }
    if(low[u0]<0)
		return 1;
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&z);
        int a,b,c;
        num=0;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[num].u=a;
            edge[num].v=b;
            edge[num++].w=c;

            edge[num].u=b;
            edge[num].v=a;
            edge[num++].w=c;
        }

        for(int i=1; i<=z; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[num].u=a;
            edge[num].v=b;
            edge[num++].w=-c;
        }
        int biao=1;
        for(int i=1; i<=n; i++)
        {
            if(Bellman(i))
            {
                printf("YES\n");
                biao=0;
                break;
            }
        }
        if(biao)
            printf("NO\n");
    }
}
/*
780ms
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 0x3f3f3f3f

using namespace std;

struct node
{
    int u,v,w;
} edge[5500];
int low[5500];
int n,m,z;
int num=0;
int Bellman(int u0)
{
    for(int i=0; i<=n; i++)
        low[i]=INF;

    low[u0]=0;                         //初始化
    for(int i=0; i<n-1; i++)              //n-1次
    {
        int flag=0;
        for(int j=0; j<num; j++)
        {
            if(low[edge[j].u]!=INF&&low[edge[j].u]+edge[j].w<low[edge[j].v])   //不同点
            {                                          //存在low[edge[j].u]!=INF,就必须有low[u0]=0;初始化
                low[edge[j].v]=low[edge[j].u]+edge[j].w;
                flag=1;
            }
        }
        if(flag==0)  //存在负权回路
            break;
    }

    for(int j=0; j<num; j++)
    {
        if(low[edge[j].u]!=INF&&low[edge[j].u]+edge[j].w<low[edge[j].v])
            return 1;
    }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&z);
        int a,b,c;
        num=0;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[num].u=a;
            edge[num].v=b;
            edge[num++].w=c;

            edge[num].u=b;
            edge[num].v=a;
            edge[num++].w=c;
        }

        for(int i=1; i<=z; i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            edge[num].u=a;
            edge[num].v=b;
            edge[num++].w=-c;
        }
        int biao=1;
        for(int i=1; i<=n; i++)
        {
            if(Bellman(i))
            {
                printf("YES\n");
                biao=0;
                break;
            }
        }
        if(biao)
            printf("NO\n");
    }
}
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-25 16:12:23

poj 3259 bellman最短路判断有无负权回路的相关文章

UVA11090 Going in Cycle!! (二分+SPFA判断有无负权)

I I U P C 2 0 0 6 Problem G: Going in Cycle!! Input: standard input Output: standard output You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a weight, which equals to sum of its edges. There are so many

[ACM] POJ 3259 Wormholes (bellman-ford最短路径,判断是否存在负权回路)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29971   Accepted: 10844 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(bellman最短路径)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 30169   Accepted: 10914 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 (bellman_ford算法判负环)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 32393   Accepted: 11771 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

bellman-ford(可判负权回路+记录路径)

#include<iostream> #include<cstdio> using namespace std; #define MAX 0x3f3f3f3f #define N 1010 int nodenum, edgenum, original; //点,边,起点 typedef struct Edge //边 { int u, v; int cost; }Edge; Edge edge[N]; int dis[N], pre[N]; bool Bellman_Ford()

poj 1860 Currency Exchange (SPFA、正权回路 bellman-ford)

链接:poj 1860 题意:给定n中货币,以及它们之间的税率,A货币转化为B货币的公式为 B=(V-Cab)*Rab,其中V为A的货币量, 求货币S通过若干此转换,再转换为原本的货币时是否会增加 分析:这个题就是判断是否存在正权回路,可以用bellman-ford算法,不过松弛条件相反 也可以用SPFA算法,判断经过转换后,转换为原本货币的值是否比原值大... bellman-ford    0MS #include<stdio.h> #include<string.h> str

UVALive - 6800 The Mountain of Gold?(Bellman-ford找负权回路,dfs)

题目链接 https://icpcarchive.ecs.baylor.edu/external/68/6800.pdf bellman-ford照模板打了一段,能够找到负权回路,问题就是判断0点在不在负权回路中了,于是写了个记忆化dfs. #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<vector> using namespace

POJ 3259 Wormholes【Bellman_ford判断负环】

题意:给出n个点,m条正权的边,w条负权的边,问是否存在负环 因为Bellman_ford最多松弛n-1次, 因为从起点1终点n最多经过n-2个点,即最多松弛n-1次,如果第n次松弛还能成功的话,则说明存在有负环 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector&

poj 3259 Wormholes【spfa判断负环】

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36729   Accepted: 13444 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