POJ 3268 Silver Cow Party (Dijkstra + 优先队列)

题意:由n个牧场,编号1到n。每个牧场有一头牛。现在在牧场x举办party,每头牛都去参加,然后再回到自己的牧场。牧场之间会有一些单向的路。每头牛都会让自己往返的路程最短。问所有牛当中最长的往返路程是多少。

思路:n最多到1000,floyd肯定超时。可以这样做,把图中所有的边先存起来,然后第一次用dijkstra求出以x为源点到每个点的最短距离。该最短距离为每头牛回家时的最短距离。然后建个新的图,将之前存的边反向加入图中。如之前有条从5到8距离为2的路,则此时向图中添加的边为从8到5距离为2的边。这样再次以x为源点求到每个点的最短距离,将两者相加,就是每头牛往返的最短距离了。求其中的最大值即可。

代码中的dijkstra算法用优先队列进行了优化。

 1 #include<stdio.h>

 2 #include<string.h>

 3 #include<iostream>

 4 #include<algorithm>

 5 #include<queue>

 6 #define maxn 1010

 7 #define maxp 100010

 8 #define inf 0x3f3f3f3f

 9 using namespace std;

10 struct node

11 {

12     int v, w, next;

13     node(){}

14     node(int a,int b){v = a; w = b;}

15     bool operator < (const node &cmp) const

16     {

17         if (w == cmp.w) return v < cmp.v;

18         else return w > cmp.w;

19     }

20 }edge[maxp];

21 int num_edge, head[maxn];

22 void init_edge()

23 {

24     num_edge = 0;

25     memset(head, -1, sizeof(head));

26 }

27 void addedge(int a,int b,int w)

28 {

29     edge[num_edge].v = b;

30     edge[num_edge].w = w;

31     edge[num_edge].next = head[a];

32     head[a] = num_edge++;

33 }

34 int n, m, x, dis1[maxn], dis2[maxn];

35 void dijkstra(int s, int dis[])

36 {

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

38         dis[i] = (i == s ? 0 : inf);

39     priority_queue<node> q;

40     q.push(node(s, dis[s]));

41     while (!q.empty())

42     {

43         node u = q.top(); q.pop();

44         for (int i = head[u.v]; i != -1; i = edge[i].next)

45         {

46             int v = edge[i].v;

47             if (dis[v] > u.w + edge[i].w)

48             {

49                 dis[v] = u.w + edge[i].w;

50                 q.push(node(v, dis[v]));

51             }

52         }

53     }

54 }

55 int e[maxp][3];

56 int main()

57 {

58     //freopen("data.in", "r", stdin);

59     scanf("%d%d%d",&n, &m, &x);

60     {

61         init_edge();

62         for (int i = 0; i < m; i++)

63         {

64             scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);

65             addedge(e[i][0], e[i][1], e[i][2]);

66         }

67         dijkstra(x, dis1);

68         init_edge();

69         for (int i = 0; i < m; i++)

70             addedge(e[i][1], e[i][0], e[i][2]);

71         dijkstra(x, dis2);

72         int tmax = -inf;

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

74             tmax = max(tmax, dis1[i] + dis2[i]);

75         printf("%d", tmax);

76     }

77     return 0;

78 }

 

你可能感兴趣的:(dijkstra)