Dijkstra_邻接表 Hlg 1419 昂贵的假花

呃~

一开始写了邻接矩阵的~结果mle了~

后来改成了邻接表的~结果tle了~

然后就用快排做了~~

但是程大学长说用堆排序~wulala~看着很麻烦吖~暂时放着~~

输入T<T组样例..>

输入n个點+m条边..

输入n个點的价值..

输入m条边<u  起点 v终点  w (u, v)的权值..>

 

其实最重要就是求单源最短路径了..

 

用邻接表可以解决点太多的问题..

 

用堆排序或优先队列可以解决  tle的问题..

 

AC代码<邻接表_优先排列>..

View Code
  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <queue>
  4 using namespace std;
  5 #define INF 0x1f1f1f1f
  6 
  7 struct ArcNode
  8 {
  9   int adjvex;
 10   long long w;
 11   ArcNode *nextarc;
 12 }node[50010];
 13 
 14 struct Node
 15 {
 16   int num;
 17   long long w;
 18   bool operator < (Node n) const
 19   {
 20     return w > n.w;
 21   }
 22 }tem, tem1;
 23 
 24 long long dist[50010];
 25 int n, e;
 26 bool fflag;
 27 ArcNode edge[50010 * 2];
 28 int nE;
 29 
 30 void Dijkstra(int v0)
 31 {
 32   int i, j;
 33   ArcNode *p = &node[v0];
 34   ArcNode *pi = NULL;
 35   priority_queue<Node> Q;
 36 
 37   while(p != NULL)
 38   {
 39   dist[p->adjvex] = p->w;
 40   p = p->nextarc;
 41   }
 42 
 43   dist[v0] = 0;
 44   tem.num = v0;
 45   tem.w = 0;
 46 
 47   Q.push(tem);
 48   while(!Q.empty())
 49   {
 50     tem = Q.top();
 51     Q.pop();
 52 
 53     for(pi = node[tem.num].nextarc; pi != NULL; pi = pi->nextarc)
 54     {
 55       tem1.w = tem.w + pi->w;
 56       tem1.num = pi->adjvex;
 57       if(tem1.w <= dist[tem1.num])
 58       {
 59         dist[tem1.num] = tem1.w;
 60         Q.push(tem1);
 61       }
 62     }
 63   }
 64 
 65 }//Dijkstra
 66 
 67 
 68 int main()
 69 {
 70   int T;
 71   int i, j, k;
 72   int a, b;
 73   long long w;
 74   ArcNode *p;
 75   long long sum;
 76   long long W[50010];
 77   while(scanf("%d", &T) != EOF)
 78   while(T--)
 79   {
 80     sum = 0;
 81     fflag = true;
 82     scanf("%d%d", &n, &e);
 83 
 84     for(i = 1; i <= n; ++i)
 85     {
 86       scanf("%lld", &W[i]);
 87       node[i].nextarc = NULL;
 88     }// for i n cin W
 89 
 90     nE = 0;
 91     for(i = 0; i < e; ++i)
 92     {
 93       scanf("%d %d %lld", &a, &b, &w);
 94 
 95       p = edge + nE++;
 96       p->adjvex = b;
 97       p->w = w;
 98       p->nextarc = node[a].nextarc;
 99       node[a].nextarc = p;
100 
101       p = edge + nE++;
102       p->adjvex = a;
103       p->w = w;
104       p->nextarc = node[b].nextarc;
105       node[b].nextarc = p;
106 
107     }//for i v cin a b w
108 
109     memset(dist, INF, sizeof(dist));
110 
111     Dijkstra(1);
112 
113     for(i = 1; i <= n; ++i)
114     {
115       if(dist[i] >= INF)
116       {
117         fflag = false;
118         break;
119       }
120     }//for i n
121 
122 
123     if(!fflag)
124     {
125       printf("No Answer\n");
126       continue;
127     }//if !flag
128     else
129     {
130       for(i = 1; i <= n; ++i)
131         sum += dist[i]*W[i];
132       printf("%lld\n", sum);
133     }// flag
134   }//while t--
135   return 0;
136 }

Mle代码<邻接矩阵>

View Code
  1 #include<stdio.h>
  2 
  3 #include<cstring>
  4 
  5 #defineINF 0x7fffffff
  6 
  7 usingnamespace std;
  8 
  9  
 10 
 11 intn, e;
 12 
 13 intEdge[50010][50010];
 14 
 15 boolS[50010];
 16 
 17 intdist[50010];
 18 
 19  
 20 
 21 voidDijkstra(int v0)
 22 
 23 {
 24 
 25     int i, j, k;
 26 
 27     for(i = 0; i < n; ++i)
 28 
 29     {
 30 
 31         dist[i] = Edge[v0][i];
 32 
 33         S[i] = false;
 34 
 35     }// for i n
 36 
 37     S[v0] = true;
 38 
 39     dist[v0] = 0;
 40 
 41     for(i = 0; i < n-1; ++i)
 42 
 43     {
 44 
 45         int min = INF;
 46 
 47         int u = v0;
 48 
 49         for(j = 0; j < n; ++j)
 50 
 51         {
 52 
 53             if(!S[j] && dist[j] <min)
 54 
 55             {
 56 
 57                u = j;
 58 
 59                 min = dist[j];
 60 
 61             }// if !S & dist < min
 62 
 63         }// for j n
 64 
 65         S[u] = true;
 66 
 67  
 68 
 69         for(k = 0; k < n; ++k)
 70 
 71         {
 72 
 73             if(!S[k] && Edge[u][k] <INF && dist[u]+Edge[u][k] < dist[k])
 74 
 75             {
 76 
 77                 dist[k] = dist[u]+Edge[u][k];
 78 
 79             }// if !S  && Edge(u, k) ***
 80 
 81         }// for k n
 82 
 83     }//for i n-1
 84 
 85  
 86 
 87 }//Dijkstra v0
 88 
 89  
 90 
 91 intmain()
 92 
 93 {
 94 
 95     int T;
 96 
 97     int i, j, k;
 98 
 99     int W[50010];
100 
101     int a, b, w;
102 
103     long long sum;
104 
105     bool flag;
106 
107  
108 
109     while(scanf("%d", &T) != EOF)
110 
111     while(T--)
112 
113     {
114 
115         memset(Edge, 0, sizeof(Edge));
116 
117         flag = true;
118 
119         sum = 0;
120 
121         scanf("%d%d", &n,&e);
122 
123         for(i = 0; i < n; ++i)
124 
125         scanf("%d", &W[i]);
126 
127  
128 
129         for(i = 0; i < n; ++i)
130 
131         {
132 
133             for(j = 0; j < n; ++j)
134 
135             {
136 
137                 if(i == j) Edge[i][j] = 0;
138 
139                 else if(Edge[i][j] == 0)Edge[i][j] = INF;
140 
141             }//for j n
142 
143         }//for i n
144 
145  
146 
147         for(i = 0; i < e; ++i)
148 
149         {
150 
151             scanf("%d%d%d", &a,&b, &w);
152 
153             Edge[a-1][b-1] = w;
154 
155             Edge[b-1][a-1] = w;
156 
157         }// cin u v w
158 
159 /*
160 
161 for(i= 0; i < n; ++i)
162 
163 {
164 
165     for(j = 0; j < n; ++j)
166 
167     if(Edge[i][j] == INF) printf("*     ");
168 
169     else printf("%d     ", Edge[i][j]);
170 
171     puts("");
172 
173 }
174 
175 ///
176 
177         Dijkstra(0);
178 
179  
180 
181         for(i = 1; i < n; ++i)
182 
183         if(dist[i] == INF)
184 
185         {
186 
187             flag = false;
188 
189             break;
190 
191         }//for no answer
192 
193         if(!flag)
194 
195         {
196 
197             printf("No Answer\n");
198 
199             continue;
200 
201         }//cout no answer
202 
203         else
204 
205         {
206 
207             for(i = 1; i < n; ++i)
208 
209             {
210 
211                 sum += dist[i]*W[i];
212 
213             }// for i n-1
214 
215  
216 
217             printf("%lld\n", sum);
218 
219         }// cout sum
220 
221  
222 
223     }// while t--
224 
225  
226 
227     return 0;
228 
229 }
230 
231  

Tle代码<邻接表..>

View Code
  1 #include<stdio.h>
  2 
  3 #include<cstring>
  4 
  5 #include<queue>
  6 
  7 #defineINF 0x1f1f1f1f
  8 
  9  
 10 
 11 structArcNode
 12 
 13 {
 14 
 15     ArcNode(){nextarc = NULL;}
 16 
 17     int adjvex;
 18 
 19     long long w;
 20 
 21     ArcNode *nextarc;
 22 
 23 }node[50010];
 24 
 25  
 26 
 27 longlong dist[50010];
 28 
 29 boolflag[50010];
 30 
 31 intn, e;
 32 
 33 boolfflag;
 34 
 35  
 36 
 37 voidDijkstra(int v0)
 38 
 39 {
 40 
 41     int i, j;
 42 
 43     ArcNode *p = &node[v0];
 44 
 45     ArcNode *pi = NULL;
 46 
 47  
 48 
 49     memset(flag, false, sizeof(flag));
 50 
 51  
 52 
 53     while(p != NULL)
 54 
 55     {
 56 
 57         dist[p->adjvex] = p->w;
 58 
 59         p = p->nextarc;
 60 
 61     }
 62 
 63     flag[v0] = true;
 64 
 65     dist[v0] = 0;
 66 
 67     for(i = 0; i < n-1; ++i)   
 68 
 69     {
 70 
 71         long long min = INF, u = v0;
 72 
 73         for(j = 1; j <= n; ++j)
 74 
 75         {
 76 
 77             if(!flag[j] && dist[j] <min)
 78 
 79             {
 80 
 81                 u = j;
 82 
 83                 min = dist[j];
 84 
 85             }//if !flag && dist <min
 86 
 87         }// for j n
 88 
 89  
 90 
 91         flag[u] = true;
 92 
 93         for(pi = &node[u]; pi; pi =pi->nextarc)
 94 
 95         {
 96 
 97             if(!flag[pi->adjvex] &&dist[u]+pi->w < dist[pi->adjvex])
 98 
 99             {
100 
101                 dist[pi->adjvex] = dist[u] +pi->w;
102 
103             }
104 
105         }
106 
107     }// for i n-1
108 
109 }//Dijkstra
110 
111  
112 
113  
114 
115 intmain()
116 
117 {
118 
119     int T;
120 
121     int i, j, k;
122 
123     int a, b;
124 
125     long long w;
126 
127     ArcNode *p;
128 
129     long long sum;
130 
131     long long W[50010];
132 
133     while(scanf("%d", &T) != EOF)
134 
135     while(T--)
136 
137     {
138 
139         sum = 0;
140 
141         fflag = true;
142 
143         scanf("%d%d", &n,&e);
144 
145  
146 
147         for(i = 1; i <= n; ++i)
148 
149         {
150 
151             scanf("%lld", &W[i]);
152 
153             node[i].nextarc = NULL;
154 
155         }// for i n cin W
156 
157         for(i = 0; i < e; ++i)
158 
159         {
160 
161             scanf("%d %d %lld",&a, &b, &w);
162 
163  
164 
165             p = new ArcNode;
166 
167             p->adjvex = b;
168 
169             p->w = w;
170 
171             p->nextarc = node[a].nextarc;
172 
173             node[a].nextarc = p;
174 
175  
176 
177             p = new ArcNode;
178 
179             p->adjvex = a;
180 
181             p->w = w;
182 
183             p->nextarc = node[b].nextarc;
184 
185             node[b].nextarc = p;
186 
187  
188 
189  
190 
191         }//for i v cin a b w
192 
193  
194 
195         memset(dist, INF, sizeof(dist));
196 
197  
198 
199         Dijkstra(1);
200 
201  
202 
203         for(i = 1; i <= n; ++i)
204 
205         {
206 
207             if(dist[i] >= INF)
208 
209             {
210 
211                 fflag = false;
212 
213                 break;
214 
215             }
216 
217         }//for i n
218 
219  
220 
221  
222 
223         if(!fflag)
224 
225         {
226 
227             printf("No Answer\n");
228 
229             continue;
230 
231         }//if !flag
232 
233         else
234 
235         {
236 
237             for(i = 1; i <= n; ++i)
238 
239             sum += dist[i]*W[i];
240 
241             printf("%lld\n", sum);
242 
243         }// flag
244 
245     }//while t--
246 
247     return 0;
248 
249 }
250 
251  

黄李龙学长版~<堆排序>

View Code
  1 #include <cstdio>
  2 
  3 #include <cstring>
  4 
  5 #include <climits>
  6 
  7 #include <iostream>
  8 
  9 #include <algorithm>
 10 
 11 using namespace std;
 12 
 13 typedef long long llong;
 14 
 15 const int MAXN = 50000 + 10;
 16 
 17  
 18 
 19 struct Edge {
 20 
 21        intto, len;
 22 
 23        Edge*next;
 24 
 25 };
 26 
 27 int nE;
 28 
 29 Edge *head[MAXN];
 30 
 31 Edge E[MAXN * 2];
 32 
 33  
 34 
 35 void addEdge(int u, int v, int len)
 36 
 37 {
 38 
 39        Edge*e = E + nE++;
 40 
 41        e->to= v;
 42 
 43        e->len= len;
 44 
 45        e->next= head[u];
 46 
 47        head[u]= e;
 48 
 49 }
 50 
 51  
 52 
 53 bool vis[MAXN];
 54 
 55 struct Node {
 56 
 57        intv;
 58 
 59        llonglen;
 60 
 61        booloperator < (const Node &B) const {
 62 
 63               returnlen > B.len;
 64 
 65        }
 66 
 67 } vHeap[MAXN];
 68 
 69  
 70 
 71 void dijkstra(int n, int s, Edge *head[],llong len[])
 72 
 73 {
 74 
 75        memset(vis,0, sizeof(vis[0]) * (n + 1));
 76 
 77        memset(len,-1, sizeof(len[0]) * (n + 1));
 78 
 79        len[s]= 0;
 80 
 81        intcnt = 1;
 82 
 83        vHeap[0].v= s;
 84 
 85        vHeap[0].len= 0;
 86 
 87        for(int i = 0; i < n; ++i) {
 88 
 89               intu = -1;
 90 
 91               llongminLen = -1;
 92 
 93               while(cnt > 0) {
 94 
 95                      u= vHeap[0].v;
 96 
 97                      minLen= vHeap[0].len;
 98 
 99                      pop_heap(vHeap,vHeap + cnt);
100 
101                      --cnt;
102 
103                      if(!vis[u]) {
104 
105                             break;
106 
107                      }
108 
109                      u= -1;
110 
111               }
112 
113               if(u == -1) break;
114 
115               vis[u]= true;
116 
117               for(Edge *e = head[u]; e; e = e->next) {
118 
119                      if(!vis[e->to] && (len[e->to] == -1 || len[e->to] > minLen +e->len)) {
120 
121                             len[e->to]= minLen + e->len;
122 
123                             vHeap[cnt].v= e->to;
124 
125                             vHeap[cnt].len= len[e->to];
126 
127                             ++cnt;
128 
129                             push_heap(vHeap,vHeap + cnt);
130 
131                      }
132 
133               }
134 
135        }
136 
137 }
138 
139  
140 
141 int weight[MAXN];
142 
143 llong len[MAXN];
144 
145  
146 
147 int main()
148 
149 {
150 
151        intnTest;
152 
153        intn, e;
154 
155        scanf("%d",&nTest);
156 
157        while(nTest--) {
158 
159               scanf("%d%d", &n, &e);
160 
161               for(int i = 1; i <= n; ++i) {
162 
163                      scanf("%d",&weight[i]);
164 
165               }
166 
167               nE= 0;
168 
169               memset(head,0, sizeof(head));
170 
171               for(int i = 0; i < e; ++i) {
172 
173                      inta, b, w;
174 
175                      scanf("%d%d %d", &a, &b, &w);
176 
177                      addEdge(a,b, w);
178 
179                      addEdge(b,a, w);
180 
181               }
182 
183  
184 
185               dijkstra(n,1, head, len);
186 
187               llongans = 0;
188 
189               for(int i = 1; i <= n; ++i) {
190 
191                      if(len[i] < 0) {
192 
193                             ans= -1;
194 
195                             break;
196 
197                      }
198 
199                      ans+= weight[i] * len[i];
200 
201               }
202 
203               if(ans >= 0) {
204 
205                      printf("%lld\n",ans);
206 
207               }else {
208 
209                      puts("NoAnswer");
210 
211               }
212 
213        }
214 
215        return0;
216 
217 }

 

原文地址:https://www.cnblogs.com/Griselda/p/2515366.html