POJ-3259-Wormholes

题目大意:利用虫洞的时光旅行,若能回到过去,则输出"YES",否则"NO"。
给定F(1<=F<=5)组数据,对应与一个farm,每组数据对应一个结果。
对于其中一组数据,给定 N , M , W ,N为点数,M为无向边数(普通路径,通过之后时间前进),W为有向边数(虫洞,通过虫洞之后时间倒退),求每组数据是否存在一条回路能使时间倒退。
解题思路:若存在这样一条回路,则图中肯定存在负环。只要判断是否有负环就行了。
AC Code (1): bellmanFord   Memory: 236K      Time: 141Ms
#include <iostream> 
#include <cstdio> 
#include <cstring> 
#define Inf 0x7fffffff 
#define MaxV 501 
#define MaxE 6000 
using namespace std; 
int F,N,M,W; 
struct Edge
{
    int to,next,time;
}edge[MaxE]; 
int size,head[MaxE]; 
void InsertEdge(int from,int to,int time) 
{  
    edge[size].to=to;
    edge[size].time=time; 
   edge[size].next=head[from];
    head[from]=size++; 
} 
int dist[MaxV]; 
bool bellmanFord() 
{  bool flag;
    int i,j,k,to; 
   memset(dist,Inf,sizeof(dist)); 
   dist[1]=0; 
   for(i=1;i<=N-1;i++) 
  {  flag=false; 
     for(j=1;j<=N;j++) 
     {  for(k=head[j];k+1;k=edge[k].next) 
          {
                to=edge[k].to; 
           if(dist[to]>dist[j]+edge[k].time) 
             {
                    flag=true;
                    dist[to]=dist[j]+edge[k].time;
                } 
          } 
       } 
      if(!flag)
        break; 
   } 
   for(j=1;j<=N;j++) 
   {   for(k=head[j];k+1;k=edge[k].next) 
      {
            to=edge[k].to;
            if(dist[to]>dist[j]+edge[k].time)
            return false;
        } 
   } 
   return true; 
} 
void init() 
{
    int i;
    int from,to,time; 
  scanf("%d%d%d",&N,&M,&W); 
  size=0;
    memset(head,-1,sizeof(head)); 
  for(i=0;i<M;i++) 
  {  scanf("%d%d%d",&from,&to,&time); 
     InsertEdge(from,to,time);InsertEdge(to,from,time); 
   } 
  for(i=0;i<W;i++) 
   {  scanf("%d%d%d",&from,&to,&time);
        InsertEdge(from,to,0-time);
    } 
} 
int main() 
{
    //freopen("in.txt","r",stdin); 
    scanf("%d",&F); 
    while(F--) 
    {
        init(); 
     if(bellmanFord())   printf("NO\n"); 
     else printf("YES\n"); 
    } 
    return 0; 
}

AC Code
 (2): spfa  Memory: 256K   Time: 141Ms
#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <queue> 
#define Inf 0x7fffffff 
#define MaxV 501 
#define MaxE 6000 
using namespace std; 
int F,N,M,W; 
struct Edge {
    int to,next,time;
}edge[MaxE]; 
int size,head[MaxE]; 
void InsertEdge(int from,int to,int time) 
{
    edge[size].to=to;
    edge[size].time=time; 
 edge[size].next=head[from];
    head[from]=size++; 
} 
int dist[MaxV];
int cot[MaxV];
bool vst[MaxV]; 
bool spfa() 
{
    queue<int> que;
    int i,from,to; 
  for(i=0;i<=N;i++)
    dist[i]=Inf;
    //这里用 memset出错
  memset(vst , 0 ,sizeof( vst)); 
  memset(cot , 0 ,sizeof( cot)); 
  dist[1]=0,vst[1]=1;
    que.push(1); 
  while(!que.empty()) 
  {
        from=que.front(),vst[from]=0,que.pop();
        cot[from]++;      
    if(cot[from]>=N)    return false
    for(i=head[from];i+1;i=edge[i].next) 
    {  to=edge[i].to; 
       if(dist[to]>dist[from]+edge[i].time) 
       {
                dist[to]=dist[from]+edge[i].time; 
           if(!vst[to]) 
             que.push(to),vst[to]=1; 
       } 
    } 
  } 
return true; 
}
void init() 
{
    int i;
    int from,to,time; 
  scanf("%d%d%d",&N,&M,&W); 
  size=0;
    memset(head,-1,sizeof(head)); 
  for(i=0;i<M;i++) 
  {  scanf("%d%d%d",&from,&to,&time); 
     InsertEdge(from,to,time);InsertEdge(to,from,time); 
  } 
  for(i=0;i<W;i++) 
  {  scanf("%d%d%d",&from,&to,&time); 
     InsertEdge(from,to,0-time); 
  } 
} 
int main()
{
    scanf("%d",&F); 
  while(F--)
  {  init(); 
     if(spfa())   printf("NO\n"); 
     else printf("YES\n"); 
  } 
return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值