http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45523
有一个国王想在首都与各个城市之间修建公路,但是他的预算太高,所以必须要降低预算。
为了降低预算,必须要有新计划,新计划必须满足每两个城市都连通,首都和城市的最短距离不会改变两个条件。
输入N各城市,首都标号为1,m条路,m行每行四个数,u,v,d,c;表示u跟v联通,并且距离为d,修路花费为c。
输出最小花费。
首先从首都开始求出到每个城市的最短路,然后再满足最短距离的情况下,更新最小花费。
1 #include <iostream> 2 #include <vector> 3 #include <queue> 4 #include <cstdio> 5 using namespace std; 6 7 const int maxn = 10010; 8 const int INF = 1<<29; 9 struct edge { 10 int to,cost,distance; 11 edge(){} 12 edge( int x,int y,int z ) { 13 to=x; 14 distance=y; 15 cost=z; 16 } 17 }; 18 19 typedef pair<int,int>P; 20 vector<edge>G[maxn]; 21 int d[maxn]; 22 int N; 23 24 void dijkstra(int s) { 25 priority_queue<P,vector<P>,greater<P> >que; 26 for(int i=1;i<=N;i++) d[i]=INF; 27 d[s]=0; 28 que.push(P(0,s)); 29 30 while(!que.empty()) { 31 P p=que.top(); que.pop(); 32 int v=p.second; 33 if(d[v]<p.first) continue; 34 for(int i=0;i<G[v].size();i++) { 35 edge e=G[v][i]; 36 if(d[e.to]>d[v]+e.distance) { 37 d[e.to]=d[v]+e.distance; 38 que.push(P(d[e.to],e.to)); 39 } 40 } 41 } 42 } 43 44 int main() 45 { 46 //freopen("a.txt","r",stdin); 47 int M; 48 while(~scanf("%d%d",&N,&M)&&(N+M)) { 49 for(int i=1;i<=N;i++) G[i].clear(); 50 int a,b,c,v; 51 for(int i=0;i<M;i++) { 52 scanf("%d%d%d%d",&a,&b,&c,&v); 53 // printf("%d %d %d %d\n",a,b,c,v); 54 G[a].push_back(edge(b,c,v)); 55 G[b].push_back(edge(a,c,v)); 56 } 57 dijkstra(1); 58 // for(int i=1;i<=N;i++) printf("%d\n",d[i]); 59 int sum=0; 60 for(int i=2;i<=N;++i) { 61 int min_cost=INF; 62 for(int j=0;j<G[i].size();++j) { 63 edge &e=G[i][j]; 64 // printf("%d %d %d\n",e.to,d[e.to],e.distance); 65 if(d[e.to]+e.distance==d[i]&&e.cost<min_cost) 66 { 67 min_cost=e.cost; 68 } 69 } 70 sum+=min_cost; 71 } 72 printf("%d\n",sum); 73 } 74 return 0; 75 }
时间: 2024-10-22 02:57:13