PKU 3159 Candies 差分约束 SPFA
http://poj.org/problem?id=3159
题意:
给出A , B , C 说A的糖果要比B的糖果多C个一下,也就是A - B <= c ,问你1号和N号之间最多能差多少个糖果。
坑爹:
一开始用了SPFA做果断超时,然后好像曾经看过网上有SLF和LLL的优化,结果就去试了一下,但是还是超时,然后
又去用优先队列,还是超时。
解法:
最后就去试了一下dijsktra和SPFA+栈,但是dijkstra还是超时了,不知道加heap优化之后会怎么样,没有去试了,
但是SPFA+栈就过了,不知道为什么,栈和队列应该的复杂度应该是差不多的,估计是数据刚好让栈不会超时。
1 #include<iostream> 2 #include<queue> 3 #include<stack> 4 using namespace std; 5 6 const int maxn = 150000 + 10; 7 const int INF = 0x3fffffff; 8 9 int n; 10 int m; 11 12 struct Edge{ 13 int from; 14 int to; 15 int values; 16 int next; 17 }edge[maxn]; 18 19 int pre[maxn]; 20 int dis[maxn]; 21 bool inq[maxn]; 22 int cntq[maxn]; 23 int cnt; 24 bool used[maxn]; 25 26 void init() 27 { 28 cnt = 0; 29 memset(pre,-1,sizeof(pre)); 30 memset(inq,0,sizeof(inq)); 31 memset(cntq,0,sizeof(cntq)); 32 int i; 33 for(i=0; i<maxn; i++) 34 { 35 dis[i] = INF; 36 } 37 } 38 39 void addEdge(int from, int to, int values) 40 { 41 edge[cnt].from = from; 42 edge[cnt].to = to; 43 edge[cnt].values = values; 44 edge[cnt].next = pre[from]; 45 pre[from] = cnt ++; 46 } 47 48 struct node { 49 friend bool operator < (node a,node b) 50 { 51 if(dis[a.index] == dis[b.index]) 52 { 53 return a.index < b.index; 54 } 55 else 56 { 57 return dis[a.index] < dis[b.index]; 58 } 59 } 60 int index; 61 }; 62 63 64 bool SPFA(int begin) 65 { 66 queue<int> Q; 67 Q.push(begin); 68 inq[begin] = true; 69 dis[begin] = 0; 70 while(!Q.empty()) 71 { 72 int front = Q.front(); 73 Q.pop(); 74 inq[front] = false; 75 int i; 76 for(i=pre[front]; i!=-1; i=edge[i].next) 77 { 78 Edge e = edge[i]; 79 if(dis[e.to] > dis[front] + e.values) 80 { 81 dis[e.to] = dis[front] + e.values; 82 if(!inq[e.to]) 83 { 84 inq[e.to] = true; 85 Q.push(e.to); 86 if(++cntq[e.to] > n) 87 { 88 return false; 89 } 90 } 91 } 92 } 93 } 94 return true; 95 } 96 97 bool SPFA_SLF(int begin) 98 { 99 deque<int> Q; 100 Q.push_back(begin); 101 inq[begin] = true; 102 dis[begin] = 0; 103 while(!Q.empty()) 104 { 105 int front = Q.front(); 106 Q.pop_front(); 107 inq[front] = false; 108 int i; 109 for(i=pre[front]; i!=-1; i=edge[i].next) 110 { 111 Edge e = edge[i]; 112 if(dis[e.to] > dis[front] + e.values) 113 { 114 dis[e.to] = dis[front] + e.values; 115 if(!inq[e.to]) 116 { 117 inq[e.to] = true; 118 if(!Q.empty()) 119 { 120 front = Q.front(); 121 if(dis[front] > dis[e.to]) 122 { 123 Q.push_front(e.to); 124 } 125 else 126 { 127 Q.push_back(e.to); 128 } 129 } 130 else 131 { 132 Q.push_back(e.to); 133 } 134 if(++cntq[e.to] > n) 135 { 136 return false; 137 } 138 } 139 } 140 } 141 } 142 return true; 143 } 144 145 bool SPFA_SLF_LLL(int begin) 146 { 147 deque<int> Q; 148 Q.push_back(begin); 149 inq[begin] = true; 150 dis[begin] = 0; 151 int sum = 0; 152 while(!Q.empty()) 153 { 154 int front = Q.front(); 155 while(dis[front] > (sum/Q.size())) 156 { 157 Q.pop_front(); 158 Q.push_back(front); 159 front = Q.front(); 160 } 161 Q.pop_front(); 162 inq[front] = false; 163 sum -= dis[front]; 164 int i; 165 for(i=pre[front]; i!=-1; i=edge[i].next) 166 { 167 Edge e = edge[i]; 168 if(dis[e.to] > dis[front] + e.values) 169 { 170 if(inq[e.to]) 171 { 172 sum -= dis[e.to]; 173 } 174 dis[e.to] = dis[front] + e.values; 175 if(!inq[e.to]) 176 { 177 inq[e.to] = true; 178 if(!Q.empty()) 179 { 180 front = Q.front(); 181 if(dis[front] > dis[e.to]) 182 { 183 Q.push_front(e.to); 184 } 185 else 186 { 187 Q.push_back(e.to); 188 } 189 } 190 else 191 { 192 Q.push_back(e.to); 193 } 194 sum += dis[e.to]; 195 if(++cntq[e.to] > n) 196 { 197 return false; 198 } 199 } 200 } 201 } 202 } 203 return true; 204 } 205 206 bool SPFA_priority(int begin) 207 { 208 priority_queue<node> Q; 209 node b; 210 b.index = begin; 211 Q.push(b); 212 inq[b.index] = true; 213 dis[b.index] = 0; 214 while(!Q.empty()) 215 { 216 node front = Q.top(); 217 Q.pop(); 218 inq[front.index] = false; 219 int i; 220 for(i=pre[front.index]; i!=-1; i=edge[i].next) 221 { 222 Edge e = edge[i]; 223 if(dis[e.to] > dis[front.index] + e.values) 224 { 225 dis[e.to] = dis[front.index] + e.values; 226 if(!inq[e.to]) 227 { 228 inq[e.to] = true; 229 node b; 230 b.index = e.to; 231 Q.push(b); 232 if(++cntq[e.to] > n) 233 { 234 return false; 235 } 236 } 237 } 238 } 239 } 240 return true; 241 } 242 243 void dijkstra(int begin) 244 { 245 dis[begin] = 0; 246 int i; 247 for(i=1; i<=n; i++) 248 { 249 int min = INF; 250 int min_j; 251 int j; 252 for(j=1; j<=m; j++) 253 { 254 if(!used[j] && min > dis[j]) 255 { 256 min = dis[j]; 257 min_j = j; 258 } 259 } 260 if(min_j == -1) 261 { 262 return ; 263 } 264 used[min_j] = true; 265 for(j=pre[min_j]; j!=-1; j=edge[j].next) 266 { 267 if(dis[edge[j].to] > dis[min_j] + edge[j].values) 268 { 269 dis[edge[j].to] = dis[min_j] + edge[j].values; 270 } 271 } 272 } 273 } 274 275 bool SPFA_stack(int begin) 276 { 277 stack<int> S; 278 S.push(begin); 279 inq[begin] = true; 280 dis[begin] = 0; 281 while(!S.empty()) 282 { 283 int front = S.top(); 284 S.pop(); 285 inq[front] = false; 286 int i; 287 for(i=pre[front]; i!=-1; i=edge[i].next) 288 { 289 Edge e = edge[i]; 290 if(dis[e.to] > dis[front] + e.values) 291 { 292 dis[e.to] = dis[front] + e.values; 293 if(!inq[e.to]) 294 { 295 inq[e.to] = true; 296 S.push(e.to); 297 if(++cntq[e.to] > n) 298 { 299 return false; 300 } 301 } 302 } 303 } 304 } 305 return true; 306 } 307 308 int main() 309 { 310 while(cin>>n>>m) 311 { 312 init(); 313 int i; 314 for(i=0; i<m; i++) 315 { 316 int a; 317 int b; 318 int values; 319 scanf("%d%d%d",&a,&b,&values); 320 addEdge(a, b, values); 321 } 322 //SPFA(1); //超时 323 //SPFA_SLF_LLL(1); //超时 324 //dijkstra(1); //超时 325 //SPFA_SLF(1); //wa 326 //SPFA_priority(1); //超时 327 SPFA_stack(1); //ac 328 printf("%d\n",dis[n]); 329 } 330 return 0; 331 }