HAUT 1262 魔法宝石 (最短路变形 or 暴力)

1262: 魔法宝石

时间限制: 2 秒  内存限制: 64 MB
提交: 537  解决: 164
提交  状态 

题目描述

小s想要创造n种魔法宝石。小s可以用ai的魔力值创造一棵第i种魔法宝石,或是使用两个宝石合成另一种宝石(不消耗魔力值)。请你帮小s算出合成某种宝石的所需的最小花费。

输入

第一行为数据组数T(1≤T≤3)。
对于每组数据,首先一行为n,m(1≤n,m≤10^5)。分别表示魔法宝石种类数和合成魔法的数量。
之后一行n个数表示a1到an。(1≤ai≤10^9)。a_i表示合成第i种宝石所需的魔力值。
之后n行,每行三个数a,b,c(1≤a,b,cn),表示一个第a种宝石和第b种宝石,可以合成一个第c种宝石。

输出

每组数据输出一行n个数,其中第i个数表示合成第i种宝石的魔力值最小花费。

样例输入

13 11 1 101 2 3

样例输出

1 1 2


思路:暴力的话,每次把所有合成方法都跑一遍,一共跑200遍。。最短路的话边(u, v, w)表示u和v能合成w,spfa中的队列存的是优化过的点


最短路代码:

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
ll dis[maxn];
int n, m;
struct node
{
    int v, w;
    node() {}
    node(int vv, int ww): v(vv), w(ww) {}
};
vector g[maxn];
bool vis[maxn];
queue q;

void spfa()
{
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        vis[u] = 0;
        for(int i = 0; i < g[u].size(); i++)
        {
            int v = g[u][i].v;
            int w = g[u][i].w;
            if(dis[u]+dis[v] < dis[w])
            {
                dis[w] = dis[u]+dis[v];
                if(!vis[w])
                {
                    q.push(w);
                    vis[w] = 1;
                }
            }
        }
    }
}

int main(void)
{
    int t;
    cin >> t;
    while(t--)
    {
        while(!q.empty()) q.pop();
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < maxn; i++)
            g[i].clear();
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
            scanf("%lld", &dis[i]);
        for(int i = 1; i <= m; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            g[u].push_back(node(v, w));
            g[v].push_back(node(u, w));
            if(!vis[u])
                vis[u] = 1, q.push(u);
            if(!vis[v])
                vis[v] = 1, q.push(v);
        }
        spfa();
        for(int i = 1; i <= n; i++)
            printf("%lld%c", dis[i], i==n ? '\n' : ' ');
    }
    return 0;
}



暴力:

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
ll dis[maxn];
int n, m, u[maxn], v[maxn], w[maxn];

int main(void)
{
    int t;
    cin >> t;
    while(t--)
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
            scanf("%lld", &dis[i]);
        for(int i = 1; i <= m; i++)
            scanf("%d%d%d", &u[i], &v[i], &w[i]);
        int bf = 200;
        while(bf--)
        {
            for(int i = 1; i <= m; i++)
                dis[w[i]] = min(dis[w[i]], dis[u[i]]+dis[v[i]]);
        }
        for(int i = 1; i <= n; i++)
            printf("%lld%c", dis[i], i==n ? '\n' : ' ');
    }
    return 0;
}



你可能感兴趣的:(最短路)