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; }