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 }

 

posted @ 2013-08-07 18:01  fenshen371  阅读(278)  评论(0编辑  收藏  举报