http://poj.org/problem?id=3259

本文详细介绍了如何使用STL中的邻接表数据结构来解决负环检测问题,通过SPFA算法实现从给定农场虫洞网络中找到是否存在负环,为时间旅行问题提供了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次用stl中的邻接表写,,以前总怕超时,,,,木想到还行,,,这一题就是判断是不是存在负环,,,

题意:一个农民在自家农场的不同地点发现一堆虫洞,每个虫洞可以回到不同长度的过去,于是这个农民想通个时间旅行回到出发点的”过去”。

#include<iostream>
#include<vector>
#include<stack>
#define N 505
#include<cstdio>
using namespace std;
struct Node{ int to,len;
       };
vector<Node> list[N];
bool visit[N];
int dist[N];
int sum[N];
int n,m,w;
void init()
{  for(int i=1;i<=n;++i)
     {list[i].clear();
       dist[i]=0xfffffff;
        visit[i]=false;
        sum[i]=0;
     }
}
bool spfa()
{   dist[1]=0,visit[1]=true,sum[1]=1;
      stack<int> Q;
      Q.push(1);
      while(!Q.empty())
      {  int u=Q.top();
        Q.pop();
        visit[u]=false;
        int len=list[u].size();
        for(int i=0;i<len;++i)
        {  if(dist[list[u][i].to]>dist[u]+list[u][i].len)
               {     dist[list[u][i].to]=dist[u]+list[u][i].len;
                      if(!visit[list[u][i].to])
                       { sum[list[u][i].to]++;
                         Q.push(list[u][i].to);
                         visit[list[u][i].to]=true;
                         if(sum[list[u][i].to]>n) return true;
                       }
                }
        }
        }
        return false;
     }
int main()
{  int test;
   Node a;
  scanf("%d",&test);
  while(test--)
  {    scanf("%d%d%d",&n,&m,&w);
        init();
         int b,c,d;
         while(m--)
         {  scanf("%d%d%d",&b,&c,&d);
             a.to=c;
             a.len=d;
             list[b].push_back(a);
             a.to=b;
             list[c].push_back(a);
         }
         while(w--)
         {  scanf("%d%d%d",&b,&c,&d);
             a.to=c;
             a.len=-d;
             list[b].push_back(a);
         }
         if(spfa()) printf("YES\n");
         else  printf("NO\n"); 
               }return 0;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值