• poj3259 最短路判环


    题意:有一些点、一些道路和一些虫洞,道路是双向的,连接两点,花费正的时间,而虫洞是单向的,连接两点,可以使时间倒退,求是否能够回到过去。

    只要明确回到过去其实就是当出现一个负环的时候,不断沿这个环走,就能够实现时间倒退了。

    然后就是判负环……

    spfa版:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 using namespace std;
     5 
     6 int head[505],next[6000],point[6000],val[6000],size;
     7 int n,dis[505],t[505];
     8 bool vis[505];
     9 
    10 void add(int a,int b,int v){
    11     int i;
    12     for(i=head[a];~i;i=next[i]){
    13         if(point[i]==b){
    14             if(val[i]>v)val[i]=v;
    15             return;
    16         }
    17     }
    18     point[size]=b;
    19     val[size]=v;
    20     next[size]=head[a];
    21     head[a]=size++;
    22 }
    23 
    24 void spfa(int s){
    25     memset(vis,0,sizeof(vis));
    26     memset(dis,0x3f,sizeof(dis));
    27     memset(t,0,sizeof(t));
    28     queue<int>q;
    29     dis[s]=0;
    30     q.push(s);
    31     vis[s]=1;
    32     t[s]++;
    33     int i;
    34     bool f=1;
    35     while(!q.empty()&&f){
    36         int u=q.front();
    37         q.pop();
    38         vis[u]=0;
    39         for(i=head[u];~i;i=next[i]){
    40             int j=point[i];
    41             if(dis[j]>dis[u]+val[i]){
    42                 dis[j]=dis[u]+val[i];
    43                 q.push(j);
    44                 t[j]++;
    45                 vis[j]=1;
    46                 if(t[j]>n)f=0;
    47             }
    48         }
    49     }
    50     if(f)printf("NO
    ");
    51     else printf("YES
    ");
    52 }
    53 
    54 int main(){
    55     int f;
    56     while(scanf("%d",&f)!=EOF){
    57         for(int q=1;q<=f;q++){
    58             int w,m,i;
    59             scanf("%d%d%d",&n,&m,&w);
    60             memset(head,-1,sizeof(head));
    61             size=0;
    62             for(i=1;i<=m;i++){
    63                 int a,b,v;
    64                 scanf("%d%d%d",&a,&b,&v);
    65                 add(a,b,v);
    66                 add(b,a,v);
    67             }
    68             for(i=1;i<=w;i++){
    69                 int a,b,v;
    70                 scanf("%d%d%d",&a,&b,&v);
    71                 add(a,b,-v);
    72             }
    73             spfa(1);
    74         }
    75     }
    76     return 0;
    77 }
    View Code

    bellman-fold版:

     1 #include<stdio.h>
     2 #include<string.h>
     3 
     4 int head[505],next[6000],point[6000],val[6000],size=0;
     5 int a,b,v,dis[505],n;
     6 
     7 void add(int a,int b,int v){
     8     int i;
     9     for(i=head[a];~i;i=next[i]){
    10         if(point[i]==b){
    11             if(val[i]>v)val[i]=v;
    12             return;
    13         }
    14     }
    15     point[size]=b;
    16     val[size]=v;
    17     next[size]=head[a];
    18     head[a]=size++;
    19 }
    20 
    21 void bf(int s){
    22     int i,j,k;
    23     memset(dis,0x3f,sizeof(dis));
    24     dis[s]=0;
    25     for(i=1;i<=n-1;i++){
    26         for(j=1;j<=n;j++){
    27             for(k=head[j];~k;k=next[k]){
    28                 int p=point[k];
    29                 if(dis[p]>dis[j]+val[k]){
    30                     dis[p]=dis[j]+val[k];
    31                 }
    32             }
    33         }
    34     }
    35     bool f=0;
    36     for(i=1;i<=n;i++){
    37         for(j=head[i];~j;j=next[j]){
    38             int p=point[j];
    39             if(dis[p]>dis[i]+val[j]){
    40                 f=1;
    41             }
    42         }
    43     }
    44     if(f)printf("YES
    ");
    45     else printf("NO
    ");
    46 }
    47 
    48 int main(){
    49     int f;
    50     while(scanf("%d",&f)!=EOF){
    51         for(int q=1;q<=f;q++){
    52             int m,w;
    53             scanf("%d%d%d",&n,&m,&w);
    54             size=0;
    55             memset(head,-1,sizeof(head));
    56             int i;
    57             for(i=1;i<=m;i++){
    58                 scanf("%d%d%d",&a,&b,&v);
    59                 add(a,b,v);
    60                 add(b,a,v);
    61             }
    62             for(i=1;i<=w;i++){
    63                 scanf("%d%d%d",&a,&b,&v);
    64                 add(a,b,-v);
    65             }
    66             bf(1);
    67         }
    68     }
    69     return 0;
    70 }
    View Code
  • 相关阅读:
    Python爬虫框架Scrapy
    继承
    c/c++面试题(7)零碎知识总结
    Linux网络编程(多人在线聊天系统)
    第一章 计算机系统漫游
    Linux网络编程(简单的时间获取服务器)
    虚函数(1)
    c/c++面试题(9)linux方向
    Linux网络编程的一般步骤(1)
    进程/线程介绍
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4785131.html
Copyright © 2020-2023  润新知