Big Christmas Tree

题意:图中每个节点和边都有权值,图中找出一颗树,树根为1使得 Σ(树中的节点到树根的距离)*(以该节点为子树的所有节点的权值之和) 结果最小;

分析:直接求出每个节点到树根的最短距离距离,之后乘上自身节点的权值求和即可;

ps:注意特判v = 0;这时cnt = 1 > v;

Djistra + priority_queue

//Accepted    2804K    141MS
#include <cstdio>
#include <cstring>
#include <utility>
#include <queue>
#include <vector>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define inf 1LL<<40
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
const int N = ;
typedef __int64 ll;
typedef pair<__int64,int> lli;//距离,编号
#define A first
#define B second
priority_queue<lli , vector<lli> , greater<lli> > q;
int v,val[N];
int head[N<<],tot;
struct edge{
int to,w,Next;
}e[N<<];
void ins(int a,int b,int w = )
{
e[++tot].Next = head[a];
e[tot].to = b;
e[tot].w = w;
head[a] = tot;
}
ll d[N];bool vis[N];
ll Djistra()
{
ll ans = ,cnt = ;
d[] = ;
q.push(lli{d[],});
while(!q.empty()){
lli t = q.top();
q.pop();
int u = t.B;
if(vis[u]) continue;
cnt++;vis[u] = true;
ans += d[u]*val[u];
for(int id = head[u];id;id = e[id].Next){
int v = e[id].to,cost = e[id].w;
if(d[v] > d[u] + cost){
d[v] = d[u] + cost;
q.push(lli{d[v],v}); }
}
}
if(cnt < v) return -;
return ans;
}
int main()
{
int T,e,kase = ;
read1(T);
while(T--){
read2(v,e);
rep1(i,,v)
read1(val[i]),d[i] = inf,vis[i] = false;
MS0(head);tot = ;
rep0(i,,e){
int a,b,w;
read3(a,b,w);
ins(a,b,w);ins(b,a,w);
}
if(v <= )out();
else{
while(!q.empty()) q.pop();
ll ret = Djistra();
if(ret == -) printf("No Answer");
else out(ret);
}
puts("");
}
return ;
}

Djistra + heap

ps:heap中的最后的位置赋值要放在最后,不好直接在break中,因为可能是出边界了,而没有赋到需要的值;

//4116K    125MS    G++    2869B
#include <cstdio>
#include <cstring>
#include <utility>
#include <queue>
#include <vector>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define inf 1LL<<40
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
const int N = ;
typedef __int64 ll;
typedef pair<__int64,int> lli;
#define A first
#define B second
int v,val[N];
int head[N<<],tot;
struct edge{
int to,w,Next;
}e[N<<];
void ins(int a,int b,int w = )
{
e[++tot].Next = head[a];
e[tot].to = b;
e[tot].w = w;
head[a] = tot;
}
ll d[N];bool vis[N];
lli heap[N],q[N];int _cnt;
bool comp(lli x,lli y)
{
return x.A < y.A;//最小堆
}
inline void push(const lli x)
{
heap[++_cnt] = x;
int son,fa;
for(son = _cnt,fa = son>>;fa >= ;son = fa,fa = son>>){
if(comp(x,heap[fa]))
heap[son] = heap[fa];
else break;
}
heap[son] = x;
}
inline lli top()
{
return heap[];
}
inline void pop()
{
lli tmp = heap[] = heap[_cnt--];
int son ,fa;
for(fa = ,son = fa<<;son <= _cnt;fa = son,son = fa<<){
if(son < _cnt && comp(heap[son|],heap[son]))
son++;
if(comp(tmp,heap[son]))break;
else heap[fa] = heap[son];
}
heap[fa] = tmp;
}
ll Djistra()
{
ll ans = ,cnt = ;
d[] = ;
push(lli{d[],});
while(_cnt){
lli t = top();
pop();
int u = t.B;
if(vis[u]) continue;
cnt++;vis[u] = true;
ans += d[u]*val[u];
for(int id = head[u];id;id = e[id].Next){
int v = e[id].to,cost = e[id].w;
if(d[v] > d[u] + cost){
d[v] = d[u] + cost;
push(lli{d[v],v});
}
}
}
if(cnt < v) return -;
return ans;
}
int main()
{
int T,e,kase = ;
read1(T);
while(T--){
read2(v,e);
rep1(i,,v)
read1(val[i]),d[i] = inf,vis[i] = false;
MS0(head);tot = ;
rep0(i,,e){
int a,b,w;
read3(a,b,w);
ins(a,b,w);ins(b,a,w);
}
if(v <= )out();
else{
_cnt = ;
ll ret = Djistra();
if(ret == -) printf("No Answer");
else out(ret);
}
puts("");
}
return ;
}

poj 3013 Big Christmas Tree Djistra的更多相关文章

  1. POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

    POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意:  圣诞树是由n个节点和e个边构成的,点编号1-n. ...

  2. poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra

    http://poj.org/problem?id=3013 Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total S ...

  3. poj 3013 Big Christmas Tree

    Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 20974   Accepted: 4 ...

  4. poj 3013 Big Christmas Tree (dij+优先级队列优化 求最短)

    模板 意甲冠军:给你一个图,1始终根,每一方都有单价值,每个点都有权重新. 每个边缘的价格值 = sum(后继结点重)*单价方值. 最低价格要求树值,它构成了一棵树n-1条边的最小价值. 算法: 1. ...

  5. SPFA/Dijkstra POJ 3013 Big Christmas Tree

    题目传送门 题意:找一棵树使得造价最少,造价为每个点的子节点造价和*边的造价和 分析:最短路跑出1根节点到每个点的最短边权值,然后每个点的权值*最短边距和就是答案,注意INF开足够大,n<=1特 ...

  6. POJ Big Christmas Tree(最短的基础)

    Big Christmas Tree 题目分析: 叫你构造一颗圣诞树,使得 (sum of weights of all descendant nodes) × (unit price of the ...

  7. POJ3013 Big Christmas Tree[转换 最短路]

    Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23387   Accepted: 5 ...

  8. Big Christmas Tree(poj-3013)最短路

    Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 25823   Accepted: 5 ...

  9. 【POJ 2486】 Apple Tree(树型dp)

    [POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Acce ...

随机推荐

  1. BugZilla的安装过程简明教程

    Bugzilla+Mysql+iis+perl模块+ ActivePerl 安装过程 (原:http://www.cnblogs.com/Warmsunshine/archive/2012/03/25 ...

  2. 手把手教你使用UICollectionView写公司的项目

    在很多app中都有这样通用的页面,一直没有机会使用UICollectionView,只是简单的看过他的使用方法.今天公司美工出图,使用了他,并且遇到了好多的坑.记录一下过程,不确定使用的方法是不是最优 ...

  3. java技术栈:一、java编程语言概述

    Java是一种编程语言,起源于20世纪90年代初Sun公司的一个叫Green的项目,该项目主要目的是是开发嵌入家用电器的分布式软件系统,从而使电器更加智能化.因为项目小组成员皆为C++的高手(那个年代 ...

  4. switch case 与 if

    case 在编程中偶尔使用到switch case语句,对于case语句的处理,出现了两种错误,现总结如下: case后必须是常量.布尔类型.字符(不能是字符串): case后如果是‘||’或者‘&a ...

  5. PHP代码实现MySQL读写分离

    关于MySQL的读写分离有几种方法:中间件,Mysql驱动层,代码控制 关于中间件和Mysql驱动层实现Mysql读写分离的方法,今天暂不做研究, 这里主要写一点简单的代码来实现由PHP代码控制MyS ...

  6. inheritance,菱形继承, 虚继承,virtual

    //菱形继承   |||||||   虚继承 #include <iostream> using namespace std; class R {     int r; public:   ...

  7. 初识 Lucene

    Lucene是一个信息检索工具库,而不是一个完整的搜索程序 搜索程序 Lucene索引核心类 Lucene索引核心类: Document: 文档对象代表一些域(field)的集合 Field: 每个文 ...

  8. linux解压命令笔记

    转载:http://www.cnblogs.com/eoiioe/archive/2008/09/20/1294681.html .tar 解包:tar xvf FileName.tar打包:tar ...

  9. PHP得出附件扩展名

    <? $filename = "mypage.asp"; //1 使用strrchr函数求得 $ext = substr(strrchr($filename, '.'), 1 ...

  10. Spark技术内幕:Client,Master和Worker 通信源码解析

    http://blog.csdn.net/anzhsoft/article/details/30802603 Spark的Cluster Manager可以有几种部署模式: Standlone Mes ...