poj 3013 单源最短路

来源:互联网 发布:明星怎么全身美白 知乎 编辑:程序博客网 时间:2024/05/22 12:02

题意比较不好理解,怎么就转化了呢

各个点的花费 = 指向该点的边的权重 乘以 该点子树中所有点的重量和

求和:各个点的重量 乘以 根节点到各个点的路径。故最短路径最小

参考:http://blog.sina.com.cn/s/blog_6635898a0100la9i.html

数字太大,不适合用邻接矩阵

#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const __int64 INF = 9999999999;const int MAXN = 50010;#define MAX 9999999#define CLR(arr, what) memset(arr, what, sizeof(arr))///全局变量 和 函数int T;int n, m;int val[MAXN];//int graph[MAXN][MAXN];__int64 dis[MAXN];bool vis[MAXN];struct node{    int u;    __int64 dis;    bool operator < (const node &a) const{        //  heap的重载 < 号的形式。        return dis > a.dis;    }};struct{    int v, w, next;}edge[2*MAXN];int edgeHead[MAXN];int k;void add_edge(int u, int v, int w){               //  为dijkstra构造邻接表。    edge[k].v = v;    edge[k].w = w;    edge[k].next = edgeHead[u];    edgeHead[u] = k ++;    edge[k].v = u;    edge[k].w = w;    edge[k].next = edgeHead[v];    edgeHead[v] = k ++;}void dijkstra(){    int i, j;    for(i = 1; i <= n; ++i)    {        dis[i] = INF;        vis[i] = false;    }    dis[1] = 0;    priority_queue<node> que;    node a;    a.u = 1;    a.dis = 0;    que.push(a);    while(!que.empty())    {        int u = que.top().u;        que.pop();        if(vis[u])            continue;        vis[u] = true;        for(i = edgeHead[u]; i != 0; i = edge[i].next)        {            int v = edge[i].v;            if(!vis[v] && dis[v] > dis[u] + edge[i].w)            {                dis[v] = dis[u] + edge[i].w;                a.u = v;                a.dis = dis[v];                que.push(a);            }        }    }}int main(){     ///    int i, j;    scanf("%d", &T);    while(T--)    {        memset(edge, 0, sizeof(edge));        memset(edgeHead, 0, sizeof(edgeHead));        scanf("%d%d", &n, &m);        for(i = 1; i <= n; ++i)        {            scanf("%d", &val[i]);        }        k = 1;        for(i = 0; i < m; ++i)        {            int from, to, value;            scanf("%d %d %d", &from, &to, &value);            add_edge(from, to, value);   //  建双向边;        }        dijkstra();        bool flag = true;        __int64 ans = 0;        for(i = 2; i <= n; ++i)        {            if(dis[i] == INF)            {                flag = false;                break;            }            ans += dis[i] * val[i];        }        if(flag)            printf("%I64d\n", ans);        else            printf("No Answer\n");    }    ///    return 0;}