POJ 3259 Wormholes(Bellman_Ford算法+SPFA版本)

题目链接

参考了很多资料,博客,看了很多对这个算法的介绍,理解了一点。

Bellman_Ford算法主要是处理权值存在负权的时候的情况复杂度,O(n*e),主要思想就是利用,如果最短路存在,则最多加入n-1条边,如果超过n-1,还可以继续松弛,就是存在负权回路。

这个题目就是判断是否存在负权回路。

 1 #include <stdio.h>

 2  #include <string.h>

 3  #define N 100000000

 4  int dis[1000],v,n;

 5  struct edge//记录所有边的信息

 6  {

 7      int sv;//起点

 8      int ev;//终点

 9      int w;//权值

10  }p[10000];

11  int Bellman_Ford()//判断是否存在负权回路

12  {

13      int i,j,z;

14      for(i = 1;i <= n-1;i ++)

15      {

16          for(j = 1;j <= v-1;j ++)

17          {

18              if(dis[p[j].ev] > dis[p[j].sv] + p[j].w)//松弛操作

19              dis[p[j].ev] = dis[p[j].sv] + p[j].w;

20          }

21      }

22      z = 1;

23      for(i = 1;i <= v-1;i ++)

24      {

25          if(dis[p[i].ev] > dis[p[i].sv] + p[i].w)

26          {

27              dis[p[i].ev] = dis[p[i].sv] + p[i].w;

28              z = 0;

29              break;

30          }

31      }

32      return z;

33  }

34  int main()

35  {

36      int t,i,m1,m2;

37      scanf("%d",&t);

38      while(t--)

39      {

40          memset(p,0,sizeof(p));

41          v = 1;

42          scanf("%d%d%d",&n,&m1,&m2);

43          for(i = 2;i <= n;i ++)//初始化dis数组

44          dis[i] = N;

45          dis[1] = 0;

46          for(i = 1;i <= m1;i ++)//输入边信息写的有点繁琐

47          {

48              scanf("%d%d%d",&p[v].sv,&p[v].ev,&p[v].w);

49              if(p[v].sv == 1)

50              {

51                  dis[p[v].ev] = p[v].w;

52              }

53              v ++;

54              p[v].sv = p[v-1].ev;

55              p[v].ev = p[v-1].sv;

56              p[v].w = p[v-1].w;

57              if(p[v].sv == 1)

58              {

59                  dis[p[v].ev] = p[v].w;

60              }

61              v ++;

62          }

63          for(i = 1;i <= m2;i ++)

64          {

65              scanf("%d%d%d",&p[v].sv,&p[v].ev,&p[v].w);

66              p[v].w = -p[v].w;

67              if(p[v].sv == 1)

68              {

69                  dis[p[v].ev] = p[v].w;

70              }

71              v ++;

72          }

73          if(Bellman_Ford())

74          printf("NO\n");

75          else

76          printf("YES\n");

77      }

78      return 0;

79  }

很搓的SPFA+邻接矩阵。居然比上边这个慢非常多。。。JUST实验一下,以后要用正规的方式写。。。

 1 #include <stdio.h>

 2 #include <string.h>

 3 #define N 100000000

 4 int dis[10000],v,n;

 5 int map[501][501];

 6 int que[1000000];

 7 int spfa()

 8 {

 9     int i,j,k,start,end;

10     int num[1000];

11     int o[1000];

12     memset(num,0,sizeof(num));

13     memset(o,0,sizeof(o));

14     memset(que,0,sizeof(que));

15     que[1] = 1;

16     o[1] = 1;

17     num[1] = 1;

18     start = end = 1;

19     while(start <= end)

20     {

21         k = 1;

22         for(i = start; i <= end; i ++)

23         {

24             o[que[i]] = 0;

25             for(j = 1; j <= n; j ++)

26             {

27                 if(dis[j] > dis[que[i]] + map[que[i]][j])

28                 {

29                     dis[j] = dis[que[i]] + map[que[i]][j];

30                     if(!o[j])

31                     {

32                         que[end + k] = j;

33                         k ++;

34                         num[j] ++;

35                         o[j] = 1;

36                         if(num[j] >= n)

37                         return 1;

38                     }

39                 }

40             }

41         }

42         start = end + 1;

43         end = end + k - 1;

44     }

45     return 0;

46 }

47 int main()

48 {

49     int t,i,j,m1,m2,sv,ev,w;

50     scanf("%d",&t);

51     while(t--)

52     {

53         memset(map,0,sizeof(map));

54         v = 1;

55         scanf("%d%d%d",&n,&m1,&m2);

56         for(i = 1;i <= n;i ++)

57         {

58             for(j = 1;j <= n;j ++)

59             map[i][j] = N;

60             map[i][j] = 0;

61         }

62         dis[1] = 0;

63         for(i = 2;i <= n;i ++)

64         dis[i] = N;

65         for(i = 1;i <= m1;i ++)

66         {

67             scanf("%d%d%d",&sv,&ev,&w);

68             if(map[sv][ev] > w)

69             {

70                 map[sv][ev] = w;

71                 map[ev][sv] = w;

72             }

73         }

74         for(i = 1;i <= m2;i ++)

75         {

76             scanf("%d%d%d",&sv,&ev,&w);

77             if(map[sv][ev] > -w)

78             {

79                 map[sv][ev] = -w;

80             }

81         }

82         if(spfa())

83             printf("YES\n");

84         else

85             printf("NO\n");

86     }

87     return 0;

88 }

你可能感兴趣的:(SPFA)