1. 程式人生 > >AOJ2249 最短路+最小花費(雙權值)

AOJ2249 最短路+最小花費(雙權值)

擴展 最小 col 滿足 fill 最短 題解 return queue

寫題解之前先罵一下這道題

xxx給數據範圍點數<1e4,邊數<2e4,結果我開2e4和3e4都RE,然後找問題一個多小時,最後我開了1e5和2e5,題面太能唬人了吧!?真是sb題面

------------------------------------------分割線------------------------------------

題目大意:給n個點和m條邊,每條邊給了起始點,距離和價格,求在保證點1到其他n-1個點的路徑都是最短路的前提下所有路的價格之和的最小值

簡單的Dijkstra變形,在松弛的時候做一下改變即可

技術分享圖片
 1 #include<iostream>
 2
#include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #define mem(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 struct edge 8 { 9 int to,nex,v,p; 10 }e[220000]; 11 int cnt,dis[110000],pri[110000]; 12 int vis[110000],fir[110000]; 13 struct node 14 { 15 int dis,pos; 16 node(){};
17 node(int a,int b):dis(a),pos(b){} 18 bool operator<(const node &x)const 19 { 20 return dis>x.dis; 21 } 22 }; 23 void add_e(int fro,int to,int v,int p) 24 { 25 e[++cnt].v=v; 26 e[cnt].to=to; 27 e[cnt].nex=fir[fro]; 28 e[cnt].p=p; 29 fir[fro]=cnt;
30 } 31 void dij(int s) 32 { 33 priority_queue<node>q; 34 q.push(node(0,1)); 35 while(!q.empty()) 36 { 37 int now=q.top().pos; 38 q.pop(); 39 if(vis[now]) continue; 40 vis[now]=1; 41 for(int i=fir[now];i;i=e[i].nex) 42 { 43 int to=e[i].to; 44 if(dis[to]>dis[now]+e[i].v&&vis[to]==0) 45 { 46 dis[to]=dis[now]+e[i].v; 47 pri[to]=e[i].p; /*松弛以後更改花費,因為是由上一個點擴展來的,為了避免重復計數, 48 花費直接就是邊的價格, 49 不理解的話可以這樣想,所有的點都是由上一個點找到的, 50 然後最終會到第一個點,所以總的花費=這個點的花費+之前點的花費,一直推直到點1*/ 51 q.push(node(dis[to],to)); 52 } 53 else if(dis[to]==dis[now]+e[i].v)//註意此處一定要用else if,因為上一個if進行之後,這個if必定滿足(或者把這個if寫在前面) 54 { 55 pri[to]=min(e[i].p,pri[to]);//距離相同選擇最小花費 56 } 57 } 58 } 59 } 60 void ini() 61 { 62 cnt=0; 63 fill(dis,dis+110000,99999999); 64 fill(pri,pri+110000,99999999); 65 mem(fir,0); 66 mem(e,0); 67 mem(vis,0); 68 } 69 int main() 70 { 71 int m,n; 72 while(scanf("%d%d",&n,&m)&&m+n) 73 { 74 ini(); 75 dis[1]=0; 76 for(int i=1;i<=m;i++) 77 { 78 int a,b,c,d; 79 cin>>a>>b>>c>>d; 80 add_e(a,b,c,d); 81 add_e(b,a,c,d); 82 } 83 dij(1); 84 int ans=0; 85 for(int i=2;i<=n;i++) 86 { 87 ans+=pri[i];//加起來就是總的花費 88 } 89 printf("%d\n",ans); 90 } 91 return 0; 92 }
View Code

AOJ2249 最短路+最小花費(雙權值)