ShortestPath:Silver Cow Party(POJ 3268)

                

                  牛的聚会

  题目大意:一群牛在一块农田的不同的点,现在他们都要去到同一个地方开会,然后现在从那个地方回到原来的位置,点与点之间的连线都是单向的,并且通过一个路径需要一定时间,问你现在哪只牛需要最多的时间?

  这一题可以这么看,回来的时候可以是从汇点(开会的地方)去到不同点的最短距离,然后从不同的点去的时候可以看做从汇点沿着路径的反方向看怎么走最短时间。

  这样看这一题就简单很多了,因为没有负边,直接Dijkstra算法,算两次即可

  

  1 #include <iostream>
  2 #include <functional>
  3 #include <algorithm>
  4 #define MAX_N 1001
  5 #define MAX_T 10000000
  6 
  7 using namespace std;
  8 
  9 typedef int Position;
 10 typedef struct edge_
 11 {
 12     int to;
 13     int cost;
 14     Position next;
 15 }Edge;
 16 typedef struct node_
 17 {
 18     Position point;
 19     Position v;
 20     int min_cost;
 21 }Node;
 22 
 23 static Node Gragh_Head[MAX_N];
 24 static Node Gragh_Head_rev[MAX_N];
 25 static Edge Gragh_Edge[MAX_N *MAX_N];
 26 static Edge Gragh_Edge_rev[MAX_N *MAX_N];
 27 static Node heap[MAX_N];
 28 static bool used[MAX_N];
 29 
 30 void Search_Dijkstra(const int, const int);
 31 int Delete_Min(int *const);
 32 void Insert(Position, Node);
 33 
 34 int main(void)
 35 {
 36     int Node_sum, Path_sum, Goal_Farm, tmp_cost, tmp_to, tmp_start;
 37 
 38     while (~scanf("%d%d%d", &Node_sum, &Path_sum, &Goal_Farm))
 39     {
 40         for (int i = 0; i <= Node_sum; i++)
 41         {
 42             Gragh_Head[i].point = -1;
 43             Gragh_Head_rev[i].point = -1;
 44         }    
 45         for (int i = 0; i < Path_sum; i++)//邻接表储存
 46         {
 47             scanf("%d%d%d", &tmp_to, &tmp_start, &tmp_cost);//起点终点反过来
 48             Gragh_Edge[i].to = tmp_to;//单向边,因为各个地方的牛要走到#X位置,相当于从#X走到各个点
 49             Gragh_Edge[i].cost = tmp_cost;
 50             Gragh_Edge[i].next = Gragh_Head[tmp_start].point;
 51             Gragh_Head[tmp_start].point = i;
 52 
 53             Gragh_Edge_rev[i].to = tmp_start;//反向边存在另一个图中
 54             Gragh_Edge_rev[i].cost = tmp_cost;
 55             Gragh_Edge_rev[i].next = Gragh_Head_rev[tmp_to].point;
 56             Gragh_Head_rev[tmp_to].point = i;
 57         }
 58         Search_Dijkstra(Node_sum, Goal_Farm);
 59     }
 60     return 0;
 61 }
 62 
 63 void Insert(Position pos, Node goal)
 64 {
 65     Position s = pos, pr;
 66 
 67     for (; s > 1; s = pr)
 68     {
 69         pr = s % 2 == 0 ? s >> 1 : (s - 1) >> 1;
 70         if (heap[pr].min_cost > goal.min_cost) heap[s] = heap[pr];
 71         else break;
 72     }
 73     heap[s] = goal;
 74 }
 75 
 76 int Delete_Min(int *const size)
 77 {
 78     Position s1, s2, pr = 1, s;
 79     Node out = heap[1], tmp = heap[(*size)--];
 80 
 81     for (; pr <= *size;)
 82     {
 83         s1 = pr << 1; s2 = s1 + 1;
 84         if (s2 <= *size)
 85         {
 86             s = heap[s1].min_cost < heap[s2].min_cost ? s1 : s2;
 87             heap[pr] = heap[s];
 88             pr = s;
 89         }
 90         else if (s1 <= *size)
 91         {
 92             heap[pr] = heap[s1]; pr = s1;
 93             break;
 94         }
 95         else break;
 96     }
 97     Insert(pr, tmp);
 98     return out.v;
 99 }
100 
101 void Search_Dijkstra(const int Node_sum, const int start)
102 {
103     int size = 0;
104     Position V, adj_v;
105 
106     memset(used, 0, sizeof(used));
107     for (int i = 1; i <= Node_sum; i++)
108     {
109         Gragh_Head[i].min_cost = MAX_T;
110         Gragh_Head[i].v = i;
111     }
112     Insert(++size, Gragh_Head[start]);
113     Gragh_Head[start].min_cost = 0;
114 
115     while (size != 0)
116     {
117         V = Delete_Min(&size);
118         used[V] = 1;
119         for (int k = Gragh_Head[V].point; k != -1; k = Gragh_Edge[k].next)
120         {
121             adj_v = Gragh_Edge[k].to;
122             if (Gragh_Head[adj_v].min_cost > Gragh_Head[V].min_cost + Gragh_Edge[k].cost)
123             {
124                 Gragh_Head[adj_v].min_cost = Gragh_Head[V].min_cost + Gragh_Edge[k].cost;
125                 if (!used[adj_v])
126                     Insert(++size, Gragh_Head[adj_v]);
127             }
128         }
129     }
130 
131     for (int i = 1; i <= Node_sum; i++)
132     {
133         Gragh_Head_rev[i].min_cost = MAX_T;
134         Gragh_Head_rev[i].v = i;
135     }
136     memset(used, 0, sizeof(used));
137     size = 0;//堆从0开始,反向边开始
138     Insert(++size, Gragh_Head_rev[start]);
139     Gragh_Head_rev[start].min_cost = 0;
140 
141     while (size != 0)
142     {
143         V = Delete_Min(&size);
144         used[V] = 1;
145         for (int k = Gragh_Head_rev[V].point; k != -1; k = Gragh_Edge_rev[k].next)
146         {
147             adj_v = Gragh_Edge_rev[k].to;
148             if (Gragh_Head_rev[adj_v].min_cost > Gragh_Head_rev[V].min_cost + Gragh_Edge_rev[k].cost)
149             {
150                 Gragh_Head_rev[adj_v].min_cost = Gragh_Head_rev[V].min_cost + Gragh_Edge_rev[k].cost;
151                 if (!used[adj_v])
152                     Insert(++size, Gragh_Head_rev[adj_v]);
153             }
154         }
155     }
156     int ans = -1;
157     for (int i = 1; i <= Node_sum; i++)
158         ans = max(ans, Gragh_Head[i].min_cost + Gragh_Head_rev[i].min_cost);
159     printf("%d\n", ans);
160 }

posted @ 2015-10-26 12:43  PhiliAI  阅读(310)  评论(0编辑  收藏  举报