POJ 3259 Wormholes

最短路问题。这个题也够DT。。出题者真会YY。

题目链接http://poj.org/problem?id=3259

两个算法。一个是bellman-ford一个就是他的队列实现。也就是对他的优化spfa算法。

bellman-ford算法

View Code
 1 #include<stdio.h>

 2 #include<string.h>

 3 #define INF 1000000

 4 int N,F,M,W,en;//N 农场个数,F 农田个数 M路径条数 W虫洞个数 en边数

 5 int dist[510];

 6 typedef struct node

 7 {

 8     int u,v;//边的两个端点

 9     int w;//权值

10 }EDGE;

11 EDGE e[INF];

12 void bellman()

13 {

14     int i,j,flag;

15     for(i=0;i<N-1;i++)

16     {

17         flag=0;

18         for(j=0;j<en;j++)

19     {

20     if (dist[e[j].v] > dist[e[j].u]+e[j].w)

21     {

22     flag=1;

23     dist[e[j].v] = dist[e[j].u]+e[j].w;

24     }

25     }

26     }

27     for(j=0;j<en;j++)

28     {

29      if(dist[e[j].v]>dist[e[j].u]+e[j].w)

30      {

31          printf("YES\n");

32          return;

33      }

34     }

35     printf("NO\n");

36 

37 }

38 int main()

39 {

40     int i;

41     scanf("%d",&F);

42     while(F--)

43     {

44         memset(dist,INF,sizeof(dist));

45         en=0;

46         scanf("%d%d%d",&N,&M,&W);

47         for(i=0;i<M;i++)

48         {

49             scanf("%d%d%d",&e[en].u,&e[en].v,&e[en].w);

50             en++;

51             e[en].u=e[en-1].v;

52             e[en].v=e[en-1].u;

53             e[en].w=e[en-1].w;

54             en++;

55         }

56        for (i=0;i<W;i++)

57      {

58       scanf("%d%d%d",&e[en].u,&e[en].v,&e[en].w); //虫洞路径  u, v, 以及倒流的时间

59       e[en].w=-e[en].w;

60        en++;

61      }

62      bellman();

63     }

64     return 0;

65 }

spfa算法

View Code
 1 #include<iostream>

 2 #include<stdio.h>

 3 #include<algorithm>

 4 #include<math.h>

 5 #include<queue>

 6 #include<string.h>

 7 #define Max 0xfffffff

 8 using namespace std;

 9 const int N=505;

10 int path[505][505];//边距

11 int dist[505];//到原点距离

12 bool spfa(int n)

13 {

14     queue<int>str;

15     bool in[N];

16     int num[N];

17     memset(in,false,sizeof(in));//是否在队列中

18     memset(num,0,sizeof(num));//进队列次数

19     for(int i=1;i<=n;++i)//初始化

20     dist[i]=Max;

21     dist[1]=0;

22     str.push(1);

23     in[1]=true;

24     num[1]=1;

25     while(!str.empty())//队列是否为空 如果队列一直到空 则说明没有负环

26     {

27         int x=str.front();

28         str.pop();

29         in[x]=false;

30         for(int i=1;i<=n;++i)

31         {

32             if(dist[i]>dist[x]+path[x][i])//找可更新点

33             {

34                 dist[i]=dist[x]+path[x][i];

35                 if(in[i]==false)//如果可更新点不再队列中

36                 {

37                     str.push(i);//进队列

38                     in[i]=true;//标记

39                     num[i]++;//进队列次数

40                     if(num[i]==n)//进队列此次到达n  说明有负环

41                     return true;

42                 }

43             }

44         }

45     }

46     return false;

47 }

48 int main()

49 {

50    // freopen("data.txt","r",stdin);

51     int n,m,w;

52     int i,j,l;

53     int f;

54     cin>>f;

55     while(f--)

56     {

57         cin>>n>>m>>w;

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

59         {

60             for(j=i;j<=n;j++)

61             {

62                 path[i][j]=path[j][i]=Max;

63             }

64         }

65         while(m--)

66         {

67            cin>>i>>j>>l;

68            if(l<path[i][j])

69            {

70                path[i][j]=path[j][i]=l;

71            }

72         }

73         while(w--)

74         {

75             cin>>i>>j>>l;

76             if((-l)<path[i][j])

77             {

78                 path[i][j]=(-l);

79             }

80         }

81         if(spfa(n)==true)

82         printf("YES\n");

83         else

84         printf("NO\n");

85     }

86     return 0;

87 }

 

你可能感兴趣的:(orm)