• Wormholes


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

    Bellman_ford : 判断是否有负权回路  282MS

    View Code
     1 #include<iostream>
     2 using namespace std ;
     3 #define INF 1>>28
     4 #define N 6000
     5 struct node
     6 {
     7     int a ;
     8     int b ;
     9     int c ;
    10 }e[N] ;
    11 int n, m, w, num ;
    12 int bellman_ford()
    13 {
    14     int dis[N] ;
    15     for(int i=1; i<=n; i++)
    16     dis[i] = INF ;
    17     dis[1] = 0 ;//以这个为源点
    18     for(int i=1; i<n; i++)//松弛n-1次就必定找出最短路径
    19     {
    20         for(int j=1; j<num; j++)
    21         if(dis[e[j].b]>dis[e[j].a]+e[j].c)
    22         dis[e[j].b] = dis[e[j].a] + e[j].c ;
    23     }
    24     for(int j=1; j<num; j++)//判断有无负环
    25     if(dis[e[j].b]>dis[e[j].a]+e[j].c)
    26     return 1 ;//表示有负环
    27     return 0 ;
    28 }
    29 int main()
    30 {
    31     int t ;
    32     cin>>t ;
    33     while(t--)
    34     {
    35        int a, b, c ;
    36        num = 1 ;
    37        cin>>n>>m>>w ;
    38        for(int i=1; i<=m; i++) //由于paths的双向性,两个方向权值相等,注意指针的移动 
    39        {
    40            cin>>a>>b>>c ;
    41            e[num].a = a ;
    42            e[num].b = b ;
    43            e[num].c = c ;
    44            num++ ;
    45            e[num].b = a ;
    46            e[num].a = b ;
    47            e[num].c = c ;
    48            num++ ;
    49        }
    50        for(int i=1; i<=w; i++)//单向边负环
    51        {
    52            cin>>a>>b>>c ;
    53            e[num].a = a ;
    54            e[num].b = b ;
    55            e[num].c = (-1)*c ;
    56            num++ ;
    57        }
    58        if(bellman_ford())
    59        cout<<"YES"<<endl ;
    60        else
    61        cout<<"NO"<<endl ;
    62     }
    63     return 0 ;
    64 }

    对Bellman_ford的小优化 ,加上flag标志  250MS

    View Code
     1 #include<iostream>
     2 using namespace std ;
     3 #define INF 1>>28
     4 #define N 6000
     5 struct node
     6 {
     7     int a ;
     8     int b ;
     9     int c ;
    10 }e[N] ;
    11 int n, m, w, num ;
    12 int bellman_ford()
    13 {
    14     int dis[N] ;
    15     for(int i=1; i<=n; i++)
    16     dis[i] = INF ;
    17     dis[1] = 0 ;//以这个为源点
    18     for(int i=1; i<n; i++)//松弛n-1次就必定找出最短路径
    19     {
    20         bool flag = false ;
    21         for(int j=1; j<num; j++)
    22         if(dis[e[j].b]>dis[e[j].a]+e[j].c)
    23         {
    24             dis[e[j].b] = dis[e[j].a] + e[j].c ;
    25             flag = true ; //relax对路径有更新 
    26         }
    27         if(!flag)//只要某一次relax没有更新,说明最短路径已经查找完毕,或者部分点不可达,可以跳出relax  
    28         break ;
    29     }
    30     for(int j=1; j<num; j++)//判断有无负环
    31     if(dis[e[j].b]>dis[e[j].a]+e[j].c)
    32     return 1 ;//表示有负环
    33     return 0 ;
    34 }
    35 int main()
    36 {
    37     int t ;
    38     cin>>t ;
    39     while(t--)
    40     {
    41        int a, b, c ;
    42        num = 1 ;
    43        cin>>n>>m>>w ;
    44        for(int i=1; i<=m; i++) //由于paths的双向性,两个方向权值相等,注意指针的移动
    45        {
    46            cin>>a>>b>>c ;
    47            e[num].a = a ;
    48            e[num].b = b ;
    49            e[num].c = c ;
    50            num++ ;
    51            e[num].b = a ;
    52            e[num].a = b ;
    53            e[num].c = c ;
    54            num++ ;
    55        }
    56        for(int i=1; i<=w; i++)//单向边负环
    57        {
    58            cin>>a>>b>>c ;
    59            e[num].a = a ;
    60            e[num].b = b ;
    61            e[num].c = (-1)*c ;
    62            num++ ;
    63        }
    64        if(bellman_ford())
    65        cout<<"YES"<<endl ;
    66        else
    67        cout<<"NO"<<endl ;
    68     }
    69     return 0 ;
    70 }

    spfa看是否有一个点进入队列等于n次,375 MS

    应该是数据比较少吧spfa竟然最慢

    View Code
     1 #include <iostream>
     2 #include<cstring>
     3 #include<queue>
     4 #define INF 0x3f3f3f
     5 using namespace std;
     6 struct node
     7 {
     8     int v,w,next;
     9 }e[6000];
    10 int head[501],vis[501],dis[501],c[501];
    11 int t ;
    12 void init()
    13 {
    14      t = 0;
    15      memset(head,-1,sizeof(head));
    16 }
    17 void add(int u,int v,int w)
    18 {
    19      e[t].v = v;
    20      e[t].w = w;
    21      e[t].next = head[u];
    22      head[u] = t;
    23      t++;
    24 }
    25 void spfa(int n)
    26 {
    27      int i, k, flag = 1;
    28      memset(vis,0,sizeof(vis));
    29      memset(c,0,sizeof(c));
    30      queue<int>q;
    31      for(i = 1; i <= n ; i++)
    32      dis[i] = INF;
    33      dis[1] = 0;
    34      q.push(1);
    35      vis[1] = 1;
    36      c[1] = 1;
    37      while(!q.empty())
    38      {
    39          k = q.front();
    40          if(c[k]==n)
    41          {
    42              flag = 0;
    43              break;
    44          }
    45 
    46          q.pop();
    47          vis[k] = 0;
    48          for(i = head[k];i!=-1 ; i = e[i].next)
    49          {
    50              if(dis[k]+e[i].w<dis[e[i].v])
    51              {
    52                  dis[e[i].v]=dis[k]+e[i].w;
    53                  if(!vis[e[i].v])
    54                  {
    55                      vis[e[i].v] = 1;
    56                      q.push(e[i].v);
    57                      c[e[i].v]++;
    58                 }
    59              }
    60          }
    61      }
    62      if(!flag)
    63      cout<<"YES"<<endl ;
    64      else
    65      cout<<"NO"<<endl ;
    66 }
    67  int main()
    68  {
    69      int i,n,m,a,b,c,w,p;
    70      cin>>p ;
    71      while(p--)
    72      {
    73          cin>>n>>m>>w ;
    74          init();
    75          for(i = 1; i <= m ; i++)
    76          {
    77              cin>>a>>b>>c ;
    78              add(a,b,c);
    79              add(b,a,c);
    80          }
    81          for(i = 1; i <= w ; i++)
    82          {
    83              cin>>a>>b>>c ;
    84              add(a,b,-c);
    85         }
    86          spfa(n);
    87     }
    88      return 0;
    89 }
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    python中单下划线和双下划线的区别
    利用faker 模块创建测试数据
    分页器基本案例思路
    小提醒
  • 原文地址:https://www.cnblogs.com/yelan/p/2935891.html
Copyright © 2020-2023  润新知