POJ3259-Wormholes-( spfa || Bellman_Ford )

Posted shoulinniao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3259-Wormholes-( spfa || Bellman_Ford )相关的知识,希望对你有一定的参考价值。

题意:有n块田,之间有m条无向边表示路径,权值表示走过需要花费的时间。有w对虫洞,虫洞是单向的,表示穿越一定时间到过去,并且回到虫洞指向的点,问一个人有没有可能通过虫洞回到某个起点,并且在从这个起点出发之前的时间,因为这样可以看到过去的自己。

解题:判断负圈,模板题。

//记录一下模板

技术图片
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;


int n,m,w;
struct node

    int to;
    int val;
;
vector<node>e[505];
int num[505];
int d[505];
bool vis[505];

bool spfa()

    queue<int>que;
    que.push(1);
    d[1]=0;
    vis[1]=true;
    num[1]=1;
    while( que.size() )
    
        int q=que.front();///q是当前结点
        que.pop();
        vis[q]=false;
        int len=e[q].size();
        for(int i=0;i<len;i++)
        
            int next=e[q][i].to;
            int cost=e[q][i].val;
            if( d[next] > d[q]+cost )
            
                d[next]=d[q]+cost;
                if( !vis[next] )///没有入队
                
                    num[next]++;
                    if( num[next]>=n )
                        return false;///入了这么多次,存在负圈
                    vis[next]=true;///入队标记
                    que.push(next);
                

            
        
    
    return true;





int main()

    int t;
    scanf("%d",&t);
    while(t--)
    

        scanf("%d%d%d",&n,&m,&w);///点、边、负边
        memset(d,inf,sizeof(d));
        memset(num,0,sizeof(num));
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=n;i++)
            e[i].clear();

        ///正边+负边总数
        int a,b,c;
        for(int i=0;i<m;i++)
        
            scanf("%d%d%d",&a,&b,&c);///起点,终点,权值
            e[a].push_back(b,c);
            e[b].push_back(a,c);
        
        for(int i=0;i<w;i++)
        
            scanf("%d%d%d",&a,&b,&c);
            e[a].push_back(b,-c);

        
        if( spfa() )
            printf("NO\n");
        else
            printf("YES\n");

    
    return 0;
spfa模板
技术图片
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

struct edge

    int from;
    int to;
    int val;
;
edge e[5555];///无向边*2+有向边
int d[505];///各个点到起点的距离
int n,m,w,cnt;
int a,b,c;

void add(int x,int y,int z)

    e[cnt].from=x;
    e[cnt].to=y;
    e[cnt].val=z;
    cnt++;


bool Bellman_Ford()//贝尔曼福特

    d[1]=0;///把1作为起点
    for(int i=0;i<n;i++)
    
        for(int j=0;j<cnt;j++)
        
            if( d[ e[j].from ] > d[ e[j].to ] + e[j].val  )
                d[ e[j].from ] = d[ e[j].to ] + e[j].val;
        
    
    for(int j=0;j<cnt;j++)///第n+1次,还能对边松弛则说明存在负环
    
        if( d[ e[j].from ] > d[ e[j].to ] + e[j].val  )
            return false;
    
    return true;


int main()

    int t;
    scanf("%d",&t);
    while(t--)
    
        memset(d,inf,sizeof(d));
        scanf("%d%d%d",&n,&m,&w);///点、边、负边
        cnt=0;///正边+负边的总边数
        for(int i=0;i<m;i++)
        
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);///无向边
        
        for(int i=0;i<w;i++)
        
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,-c);
        
        if( Bellman_Ford() )
            printf("NO\n");
        else
            printf("YES\n");

    
    return 0;
Bellman_Ford模板

 

以上是关于POJ3259-Wormholes-( spfa || Bellman_Ford )的主要内容,如果未能解决你的问题,请参考以下文章

「POJ3259」Wormholes - SPFA判负环

POJ 3259 Wormholes spfa 判负环

POJ 3259 Wormholes(SPFA判负环)

POJ3259 Wormholes(SPFA判断负环)

POJ-3259 Wormholes(判负环,spfa算法)

POJ 3259 Wormholes(SPFA+邻接表)