poj 3013 Big Christmas Tree
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 3013 Big Christmas Tree相关的知识,希望对你有一定的参考价值。
题意:输入v个节点和e条边(0 ≤ v, e ≤ 50000) 的图,第二行输入每个节点的权值,之后e行输入每条边的端点和权值;
问是否能找出一棵树,使得树中的边权乘以该边下面的子孙节点权值之和的sigma总和最小;(树以1为根节点)
Sample Input
1
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
1210
分析:如果计算最小乘积时真的就是按照题目给的,对于每条边去累加该边下面的节点的权值之和;但是这样直接被忽悠了。。反过来看,就相当于每个节点计算了几次。。(几次指的是到根节点的边权之和)这样就直接Djistra跑单源最短路即可;使用优先队列,直接确定点的最短路径长,所以可以在djistra中计算出ans;同时还可以看是否是连通图;
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=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;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>9) out(a/10); putchar(a%10+‘0‘); } const int N = 50050; 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<<1],tot; struct edge{ int to,w,Next; }e[N<<1]; void ins(int a,int b,int w = 0) { 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 = 0,cnt = 0; d[1] = 0; q.push(lli{d[1],1}); 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 -1; return ans; } int main() { int T,e,kase = 1; read1(T); while(T--){ read2(v,e); rep1(i,1,v) read1(val[i]),d[i] = inf,vis[i] = false; MS0(head);tot = 0; rep0(i,0,e){ int a,b,w; read3(a,b,w); ins(a,b,w);ins(b,a,w); } if(v <= 1)out(0); else{ while(!q.empty()) q.pop(); ll ret = Djistra(); if(ret == -1) printf("No Answer"); else out(ret); } puts(""); } return 0; }
以上是关于poj 3013 Big Christmas Tree的主要内容,如果未能解决你的问题,请参考以下文章
POJ3013-Big Christmas Tree-最短路