Big Christmas Tree
题目链接:POJ - 3013题意:要求建一棵圣诞树, 1是根节点, 每条边的权重是这条边下的所有子节点权重之和*边的长度;要建树的代价最小;
对于每个节点来说, 他提供的代价就是他到根节点的距离*自身权重;
所以这是个最短路问题;
dijkstra算法要用堆优化(优先队列), 否则会TE, 还有就是INF=0x3f3f3f3f3f3f3f3f,不然会WA;
SPFA也能过;
dijkstra优化:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn=50010;
const long long INF = 0x3f3f3f3f3f3f3f3f;
int V, E;
struct node{
int v, nex;
long long w;
}edge[maxn*2];
int cnt, head[maxn];
void add(int u, int v, long long w){
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
long long val[maxn];
int vis[maxn];
long long dis[maxn];
struct Node{
int u;
long long w;
Node(){};
bool operator < (const Node &a) const{
return w>a.w;
}
};
priority_queue<Node> que;
void dijkstra(){
memset(dis, INF, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[1]=0;
Node temp;
temp.u=1;
temp.w=0;
que.push(temp);
while(!que.empty()){
temp=que.top();
que.pop();
if(vis[temp.u]) continue;
vis[temp.u]=1;
for(int i=head[temp.u]; i!=-1; i=edge[i].nex){
if(!vis[edge[i].v]&&dis[edge[i].v]>dis[temp.u]+edge[i].w){
dis[edge[i].v]=dis[temp.u]+edge[i].w;
Node p;
p.u=edge[i].v;
p.w=dis[p.u];
que.push(p);
}
}
}
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &V, &E);
memset(head, -1, sizeof(head));
for(int i=1; i<=V; i++){
scanf("%lld", &val[i]);
}
int a, b;
long long c;
cnt=0;
for(int i=0; i<E; i++){
scanf("%d%d", &a, &b);
scanf("%lld", &c);
add(a, b, c);
add(b, a, c);
}
dijkstra();
long long ans=0;
int flag=0;
for(int i=1; i<=V; i++){
if(dis[i]>=INF){
flag=1;
break;
}
ans+=dis[i]*val[i];
}
if(flag) printf("No Answer\n");
else printf("%lld\n", ans);
}
return 0;
}
SPFA:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const int maxn=50010;
int V, E;
struct node{
int v, nex;
long long w;
}edge[maxn*2];
int head[maxn];
int cnt;
void add(int u, int v, long long w){
edge[cnt].v=v;
edge[cnt].nex=head[u];
edge[cnt].w=w;
head[u]=cnt++;
}
long long val[maxn];
queue<int> que;
long long dis[maxn];
int vis[maxn];
void SPFA(){
memset(vis, 0, sizeof(vis));
memset(dis, INF, sizeof(dis));
dis[1]=0;
que.push(1);
while(!que.empty()){
int u=que.front();
que.pop();
vis[u]=0;
for(int i=head[u]; i!=-1; i=edge[i].nex){
if(dis[edge[i].v]>dis[u]+edge[i].w){
dis[edge[i].v]=dis[u]+edge[i].w;
if(vis[edge[i].v]) continue;
que.push(edge[i].v);
vis[edge[i].v]=1;
}
}
}
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &V, &E);
cnt=0;
memset(head, -1, sizeof(head));
for(int i=1; i<=V; i++){
scanf("%lld", &val[i]);
}
int a, b;
long long c;
for(int i=0; i<E; i++){
scanf("%d%d%lld", &a, &b, &c);
add(a, b, c);
add(b, a, c);
}
SPFA();
long long ans=0;
int flag=0;
for(int i=1; i<=V; i++){
if(dis[i]>=INF){
flag=1;
break;
}
ans+=dis[i]*val[i];
}
if(flag){
printf("No Answer\n");
}
else{
printf("%lld\n", ans);
}
}
return 0;
}