1. 程式人生 > >poj3013Big Chrismas Tree——樹轉換spfa

poj3013Big Chrismas Tree——樹轉換spfa

== int %d ron blank body href type scanf

題目:http://poj.org/problem?id=3013

看似生成樹,實則最短路,可以將題意轉化為點權*根到此點的邊權和(最短路使其最小)。

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
queue<int>q;
int t,n,m,head[50005],ct,s[50005];
bool in[50005];
ll dis[50005],INF=1e10,ans;
struct N{ int to,next,w; N(int t=0,int n=0,int ww=0):to(t),next(n),w(ww) {} }edge[100005]; int main() { scanf("%d",&t); while(t--) { ct=0; memset(head,0,sizeof head); memset(in,0,sizeof in); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf(
"%d",&s[i]),dis[i]=INF; for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); edge[++ct]=N(y,head[x],z);head[x]=ct; edge[++ct]=N(x,head[y],z);head[y]=ct; } while(q.size())q.pop(); dis[1]=0
;q.push(1);in[1]=1; while(q.size()) { int x=q.front();q.pop(); in[x]=0; for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(dis[u]>dis[x]+edge[i].w) { dis[u]=dis[x]+edge[i].w; if(!in[u])in[u]=1,q.push(u); } } } bool flag=0;ans=0; for(int i=1;i<=n;i++) { if(dis[i]==INF) { flag=1;break; } ans+=dis[i]*s[i]; } if(flag)printf("No Answer\n"); else printf("%lld\n",ans); } return 0; }

poj3013Big Chrismas Tree——樹轉換spfa