题意:
重点理解:price of an edge will be (sum of weights of all descendant nodes) × (unit price of the edge);看似求类似最小生成树的题,其实仔细想想可以转换成最短路的问题;
即:给你一幅无向图,求root点到每个点的最短距离(dis[i])*每个点的权值(W[i])的和;price of an edge will be (sum of weights of all descendant nodes) × (unit price of the edge)
源代码:
/*SPFA*/ /* 思路: ans=root到每个结点的最短距离(dis[i])*每个点的权值(W[i])的和 注意点: (1):无向图 (2):用__int64 */ /*AC代码:672ms*/ #include <iostream> #include <cstdio> #include <memory.h> #include <queue> #include <algorithm> #define MAXN 50005 #define min(a,b) (a<b?a:b) #define max(a,b) (a>b?a:b) #define INF 1e18 using namespace std; struct edge { int u,v,next; __int64 w; }E[2*MAXN]; int head[MAXN],ecnt; __int64 W[MAXN]; __int64 dis[MAXN]; bool vis[MAXN]; int N,M; void Insert(int u,int v,__int64 w) { E[ecnt].u=u; E[ecnt].v=v; E[ecnt].w=w; E[ecnt].next=head[u]; head[u]=ecnt++; } void Init() { int i,u,v; __int64 w; memset(head,-1,sizeof(head));ecnt=0; scanf("%d%d",&N,&M); for(i=1;i<=N;i++) scanf("%I64d",&W[i]); for(i=1;i<=M;i++) { scanf("%d%d%I64d",&u,&v,&w); Insert(u,v,w); Insert(v,u,w); } } queue<int>Q; void SPFA() { int i,u,v; __int64 w; while(!Q.empty()) Q.pop(); memset(vis,false,sizeof(vis)); for(i=1;i<=N;i++) dis[i]=INF; dis[1]=0; vis[1]=true; Q.push(1); while(!Q.empty()) { u=Q.front();Q.pop(); vis[u]=false; for(i=head[u];i!=-1;i=E[i].next) { v=E[i].v;w=E[i].w; if(dis[v]>dis[u]+w) { dis[v]=dis[u]+w; if(!vis[v]) { vis[v]=true; Q.push(v); } } } } } void Solve() { int i; SPFA(); __int64 ans=0; bool ok=true; for(i=1;i<=N;i++) { if(dis[i]==INF) {ok=false;break;} ans+=dis[i]*W[i]; } if(!ok) printf("No Answer\n"); else printf("%I64d\n",ans); } int main() { int T; scanf("%d",&T); while(T--) { Init(); Solve(); } return 0; }