zoukankan      html  css  js  c++  java
  • 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
    ");
            else
                printf("YES
    ");
    
        }
        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
    ");
            else
                printf("YES
    ");
    
        }
        return 0;
    }
    Bellman_Ford模板
  • 相关阅读:
    svn diff color
    svn 教程
    第40章 CAN—通讯实验—零死角玩转STM32-F429系列
    第39章 ETH—Lwip以太网通信—零死角玩转STM32-F429系列
    第38章 I2S—音频播放与录音输入—零死角玩转STM32-F429系列
    第37章 基于SD卡的FatFs文件系统—零死角玩转STM32-F429系列
    第36章 SDIO—SD卡读写测试—零死角玩转STM32-F429系列
    第35章 WWDG—窗口看门狗—零死角玩转STM32-F429系列
    第33章 TIM—电容按键检测—零死角玩转STM32-F429系列
    第34章 IWDG—独立看门狗—零死角玩转STM32-F429系列
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/11219789.html
Copyright © 2011-2022 走看看