poj 3013 最短路变形

来源:互联网 发布:mac怎么升级到os10.11 编辑:程序博客网 时间:2024/06/05 10:04

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

给出n个点,m个边。给出每个点的权值,每个边的权值。在m条边中选n-1条边使这n个点成为一棵树,root=1,求这棵树的最小费用,费用=树上每条边*子树中各顶点的权值。


思路:转化一下,发现每条边*子树中各定点的权值=各个点*点到根的最短路,于是转化成了root到各个点的最短路,又到不了的点则说明无法建树。

#pragma comment(linker, "/STACK:36777216")#pragma GCC optimize ("O2")#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <queue>#include <map>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))#define clr1(x) memset(x,-1,sizeof(x))#define eps 1e-9const double pi = acos(-1.0);typedef long long LL;typedef unsigned long long ULL;const int modo = 1e9 + 7;const int INF = 0x3f3f3f3f;const int inf = 0x3fffffff;const LL _inf = 1e18;const int maxn = 50005,maxm = 50005;struct edge{    int v,w,next;    edge(){};    edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};}e[maxm<<1];int head[maxn],inq[maxn],vw[maxn];LL dist[maxn];int n,m,ecnt;void init(){    clr1(head);    ecnt = 0;    fill(dist,dist+maxn,_inf);    clr0(inq);}void add(int u,int v,int w){    e[ecnt] = edge(v,w,head[u]);    head[u] = ecnt++;    e[ecnt] = edge(u,w,head[v]);    head[v] = ecnt++;}void spfa(int src){    queue<int> q;    q.push(src);dist[src] = 0,inq[src] = 1;    while(!q.empty()){        int cur = q.front();        q.pop();inq[cur] = 0;        for(int i = head[cur];i != -1;i = e[i].next){            int nxt = e[i].v;            if(dist[nxt] > dist[cur] + e[i].w){                dist[nxt] = dist[cur] + e[i].w;                if(!inq[nxt])                    inq[nxt] = 1,q.push(nxt);            }        }    }}void work(){    LL ans = 0;    for(int i = 2;i <= n;++i){        if(dist[i] >= _inf){            puts("No Answer");            return ;        }        ans += dist[i] * vw[i];    }    printf("%I64d\n",ans);}int main(){    int u,v,w,_;    RD(_);    while(_--){        RD2(n,m);        init();        for(int i = 1;i <= n;++i)            RD(vw[i]);        while(m--){            RD3(u,v,w);            add(u,v,w);        }        spfa(1);        work();    }    return 0;}


0 0
原创粉丝点击