AOJ 2249 Road Construction(Dijkstra+优先队列)

 

【题目大意】 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2249

 

【题目大意】

  一张无向图,建造每条道路需要的费用已经给出,
  现在求在起点到每个点都是最短路的情况下的最小修路费用

 

【题解】

  考虑到最后的图一定是树形的,因此只要保留每个点与其父节点之间的边的费用最小值即可
  在计算最短路的同时不断更新费用

 

【代码】

#include <cstdio>  
#include <cstring> 
#include <queue> 
#include <utility> 
using namespace std;  
const int N=2000100;  
const int INF=~0U>>2;  
typedef pair<int,int>seg;  
priority_queue<seg,vector<seg>,greater<seg> >q;     
int d[N],D[N],head[N],u[N],v[N],w[N],nxt[N],cost[N],n,m,a,b,c,cc,ed=0,H,x[N],y[N]; 
bool vis[N];  
void add(int a,int b,int c,int cos){  
    u[++ed]=a,v[ed]=b,w[ed]=c;cost[ed]=cos;
    nxt[ed]=head[u[ed]]; head[u[ed]]=ed;     
}     
void Dijkstra(int src){  
    memset(vis,0,sizeof(vis));  
    for(int i=1;i<=n;i++)d[i]=INF;  
    d[src]=0;  
    q.push(make_pair(d[src],src));  
    while(!q.empty()){  
        seg now=q.top(); q.pop();  
        int x=now.second;  
        if(d[x]<now.first)continue; 
        for(int e=head[x];e!=-1;e=nxt[e]) 
        if(d[v[e]]>d[x]+w[e]){ 
            d[v[e]]=d[x]+w[e];  
            D[v[e]]=cost[e];
            q.push(make_pair(d[v[e]],v[e]));  
        }else if(d[v[e]]==d[x]+w[e]){
            D[v[e]]=min(cost[e],D[v[e]]);
        }
    }
} 
int main(){
	  while(~scanf("%d%d",&n,&m),m+n){
		    memset(head,-1,sizeof(head));ed=0;
		    memset(nxt,-1,sizeof(nxt));
	      while(m--){
	    	    scanf("%d%d%d%d",&a,&b,&c,&cc);
	    	    add(a,b,c,cc);add(b,a,c,cc);
	      }Dijkstra(1);
	      int ans=0;
	      for(int i=2;i<=n;i++)ans+=D[i];
		    printf("%d\n",ans);
	  }return 0;
}

  

posted @ 2016-11-22 20:06  forever97  阅读(351)  评论(0编辑  收藏  举报