zoukankan      html  css  js  c++  java
  • poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra

    http://poj.org/problem?id=3013

    Big Christmas Tree
    Time Limit: 3000MS   Memory Limit: 131072K
    Total Submissions: 19009   Accepted: 4048

    Description

    Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of the tree is shown in right picture.

    The tree can be represented as a collection of numbered nodes and some edges. The nodes are numbered 1 through n. The root is always numbered 1. Every node in the tree has its weight. The weights can be different from each other. Also the shape of every available edge between two nodes is different, so the unit price of each edge is different. Because of a technical difficulty, price of an edge will be (sum of weights of all descendant nodes) × (unit price of the edge).

    Suby wants to minimize the cost of whole tree among all possible choices. Also he wants to use all nodes because he wants a large tree. So he decided to ask you for helping solve this task by find the minimum cost.

    Input

    The input consists of T test cases. The number of test cases T is given in the first line of the input file. Each test case consists of several lines. Two numbers v, e (0 ≤ v, e ≤ 50000) are given in the first line of each test case. On the next line, v positive integers wi indicating the weights of v nodes are given in one line. On the following e lines, each line contain three positive integers a, b, c indicating the edge which is able to connect two nodes a and b, and unit price c.

    All numbers in input are less than 216.

    Output

    For each test case, output an integer indicating the minimum possible cost for the tree in one line. If there is no way to build a Christmas tree, print “No Answer” in one line.

    Sample Input

    2
    2 1
    1 1
    1 2 15
    7 7
    200 10 20 30 40 50 60
    1 2 1
    2 3 3
    2 4 2
    3 5 4
    3 7 2
    3 6 3
    1 5 9

    Sample Output

    15
    1210

    Source

    POJ Monthly--2006.09.29, Kim, Chan Min (kcm1700@POJ)
     
    【题解】:
      变向的最短路劲问题:
          题目意思其实就是求各点到1节点的 最短路径*节点权值 之和,根节点1的权值没有用的
    【code】:
      1 /**
      2 Judge Status:Accepted      Memory:2880K
      3 Time:610MS      Language:G++
      4 Code Length:2062B  Author:cj
      5 */
      6 
      7 #include<iostream>
      8 #include<queue>
      9 #include<stdio.h>
     10 #include<string.h>
     11 #include<stdlib.h>
     12 
     13 #define N 50005
     14 #define INF 1000000000000
     15 using namespace std;
     16 
     17 struct Edge  //保存边的结构体
     18 {
     19     int to;   //边连接的另外个点
     20     int next;  //下一个搜索的节点
     21     int w;  //节点的权值
     22 }edge[N<<1];
     23 
     24 struct Nod
     25 {
     26    int u;   //进入队列中的点
     27    __int64 dis;  //到该点的距离
     28 }now,temp;
     29 
     30 bool operator< (Nod a,Nod b)   //优先队列重载'<'运算符
     31 {
     32     return a.dis>b.dis;  //小到大
     33 }
     34 
     35 int weight[N],head[N],visit[N];
     36 __int64 dis[N];  //第一点到各点的最小距离
     37 
     38 void init(int n)  //初始化
     39 {
     40     int i;
     41     for(i=0;i<=n;i++)
     42     {
     43         visit[i] = 0;
     44         dis[i] = INF;
     45         head[i] = -1;
     46     }
     47 }
     48 
     49 void Dijkstra(int s)
     50 {
     51     int i,v;
     52     dis[s] = 0;
     53     priority_queue<Nod> p_q;  //优先队列 你懂的
     54     temp.dis = 0;
     55     temp.u = s;
     56     p_q.push(temp);
     57     while(!p_q.empty())
     58     {
     59         temp = p_q.top();  //每次去的都是距离起点最小的点(优先队列的性质)
     60         p_q.pop();
     61         if(visit[temp.u])  continue;
     62         visit[temp.u] = 1;
     63         for(i=head[temp.u];i!=-1;i=edge[i].next)  //每次遍历跟这个点有连接的所有点
     64         {
     65             v = edge[i].to;
     66             if(!visit[v]&&dis[v]>dis[temp.u]+edge[i].w)
     67             {
     68                 dis[v] = dis[temp.u]+edge[i].w;  //距离更新
     69                 now.u = v;
     70                 now.dis = dis[v];
     71                 p_q.push(now); //压入队列
     72             }
     73         }
     74     }
     75 }
     76 
     77 int main()
     78 {
     79     int t;
     80     scanf("%d",&t);
     81     while(t--)
     82     {
     83         int m,n;
     84         scanf("%d%d",&n,&m);
     85         int i;
     86         for(i=0;i<n;i++)    scanf("%d",weight+i);
     87         int id = 0;
     88         init(n);
     89         int a,b,c;
     90         for(i=0;i<m;i++)
     91         {
     92             scanf("%d%d%d",&a,&b,&c);
     93             a--,b--;
     94             edge[id].to = b;
     95             edge[id].w = c;
     96             edge[id].next = head[a];
     97             head[a] = id++;  //将边 a --> b保存
     98 
     99             edge[id].to = a;
    100             edge[id].w = c;
    101             edge[id].next = head[b];
    102             head[b] = id++;  //将边 b --> a保存
    103         }
    104         Dijkstra(0);
    105         __int64 res = 0;
    106         for(i=0;i<n;i++)
    107         {
    108             if(dis[i]==INF) break;
    109             res += dis[i]*weight[i];
    110         }
    111         if(i<n) puts("No Answer");
    112         else printf("%I64d
    ",res);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    索引访问中的access和filter
    分页SQL走全表扫描导致TEMP耗尽
    多表关联的分页SQL经典案例
    分页技术COUNT STOPKEY和SORT ORDER BY
    FILTER再来一例
    错误的选择了HASH JOIN!
    dojo加载树报错
    dojo中获取表格中某一行的某个值
    dojo处理删除操作报错
    分页语句优化
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3248902.html
Copyright © 2011-2022 走看看