Coder Space

PKU 3013 Big Christmas Tree--- 单源最短路径Dijkstra + heap

题意:给定一个无向图,要求构造一棵以1为根的树T,使得花费和最小。

边权(花费):S(边的price*S(边子孙节点的weight)),可以转化为S(第个点的weight*S(该点到源点每条边上的price))
即所求为:ans = Sdist[i] * weight[i]。因weight[i]是确定的,故原题转化为求最短路问题。

因题目数目较大,故用Dijkstra+heap优化。

  1#include<iostream>
  2#include<queue>
  3#include<limits>
  4#include<vector>
  5
  6using namespace std;
  7
  8typedef unsigned long long u64_T;
  9
 10const int maxN = 50001;
 11const int maxM = 100010;
 12const u64_T INF = numeric_limits<u64_T>::max();
 13
 14//边结构
 15struct Edge
 16{
 17    int e;
 18    u64_T p;
 19    Edge *next;
 20}
;
 21
 22//节点结构
 23struct Node
 24{
 25    int v;
 26    u64_T len;
 27
 28    bool operator < (const Node &node) const
 29    {
 30        return len < node.len;
 31    }

 32}
;
 33
 34Edge *G[maxN];
 35u64_T weight[maxN];
 36
 37int mSet;
 38
 39//输入时,加边
 40void addEdge(int u, int v, u64_T w)
 41{
 42    Edge *ptr = new Edge;
 43    ptr->= v;
 44    ptr->= w;
 45    ptr->next = G[u];
 46    G[u] = ptr;
 47}

 48
 49//Dijkstra算法求最短路
 50u64_T Dijkstra(int n,int s)
 51{
 52    priority_queue<Node> q;    
 53    u64_T dist[maxN];
 54    Node cur,nex;
 55
 56    for(int i = 1;i <= n;i++)
 57    {
 58        dist[i] = INF;
 59    }

 60    dist[s] = 0;
 61    cur.v = s;
 62    cur.len = 0;
 63    q.push(cur);
 64
 65    while(!q.empty())
 66    {
 67        cur = q.top();
 68        q.pop();
 69
 70        if( cur.len == dist[cur.v] )
 71        {
 72            for(Edge* ptr = G[cur.v]; ptr != NULL; ptr = ptr->next)
 73            {
 74                u64_T newDist = dist[cur.v] + ptr->p;
 75                if( newDist < dist[ptr->e] )
 76                {
 77                    dist[ptr->e] = newDist;
 78                    nex.v = ptr->e;
 79                    nex.len = newDist;
 80                    q.push(nex);
 81                }

 82            }

 83        }

 84    }

 85    for(int i = 1;i <= n; i++)
 86    {
 87        if(dist[i] == INF)
 88        {
 89            return INF;
 90        }

 91    }

 92
 93    u64_T ans = 0;
 94    for(int i = 1;i <= n; i++)
 95    {
 96        ans += dist[i] * weight[i];
 97    }

 98    return ans;
 99}

100
101int main()
102{
103    int T;
104    int v,e;
105    int a,b;
106    u64_T c;
107
108    int i;
109
110    scanf("%d",&T);
111    while(T--)
112    {
113        scanf("%d%d",&v,&e);
114
115        mSet = 0;
116
117        for(i=1;i<=v;i++)
118        {
119            scanf("%I64u",&weight[i]);
120            G[i] = NULL;
121        }

122        for(i=0;i<e;i++)
123        {
124            scanf("%d%d%I64u",&a,&b,&c);
125            addEdge(a,b,c);
126            addEdge(b,a,c);
127        }

128
129        u64_T ans = Dijkstra(v,1);
130
131        if(ans == INF)
132        {
133            printf("No Answer\n");            
134        }

135        else
136        {
137            printf("%I64u\n",ans);            
138        }

139    }

140    return 0;
141}

142

posted on 2010-05-09 02:30 David Liu 阅读(372) 评论(0)  编辑 收藏 引用 所属分类: 图论


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


My Links

Blog Stats

常用链接

留言簿

文章分类

文章档案

搜索

最新评论