Codeforces Gym 100269 Dwarf Tower (最短路)

题目连接:

http://codeforces.com/gym/100269/attachments

Description

Little Vasya is playing a new game named “Dwarf Tower”. In this game there are n different items,
which you can put on your dwarf character. Items are numbered from 1 to n. Vasya wants to get the
item with number 1.
There are two ways to obtain an item:
? You can buy an item. The i-th item costs ci money.
? You can craft an item. This game supports only m types of crafting. To craft an item, you give
two particular different items and get another one as a result.
Help Vasya to spend the least amount of money to get the item number 1.

Input

The first line of input contains two integers n and m (1 ≤ n ≤ 10 000; 0 ≤ m ≤ 100 000) — the number
of different items and the number of crafting types.
The second line contains n integers ci — values of the items (0 ≤ ci ≤ 109
).
The following m lines describe crafting types, each line contains three distinct integers ai, xi, yi — ai is the item that can be crafted from items xi and yi (1 ≤ ai , xi , yi ≤ n; ai ?= xi ; xi ?= yi ; yi ?= ai).

Output

The output should contain a single integer — the least amount of money to spend.

Sample Input

5 3
5 0 1 2 5
5 2 3
4 2 3
1 4 5

Sample Output

2

题意:

  对与一个物品,你可以选择购买获得,但是要花费ci , 或者是通过 xi yi 合成。

  要你用最小的花费得到物品1.

题解:

  我们对于每一个物品都应该花最小的花费的到。 a可以通过x, y合成。那么从x去到a的费用就是 c[y] 。(因为你已经跑到了x点,表示你已经有了x了)。

  在建一个大原点 0, 0到每个点的费用为c[i] 。然后用0这里跑一次Dij 。这样你就可以得到了获得物品i 的最小花费。

  在跑一下m次合成,找到最小的花费。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <vector>
  8 #include <queue>
  9 #include <map>
 10 #include <stack>
 11 #include <set>
 12 using namespace std;
 13 typedef long long LL;
 14 typedef unsigned long long uLL;
 15 #define ms(a, b) memset(a, b, sizeof(a))
 16 #define rep(a, b) for(int a = 0;a<b;a++)
 17 #define rep1(a, b) for(int a = 1;a<=b;a++)
 18 #define pb push_back
 19 #define mp make_pair
 20 #define eps 0.0000000001
 21 #define IOS ios::sync_with_stdio(0);cin.tie(0);
 22 const LL INF = 0x3f3f3f3f3f3f3f3f;
 23 const int inf = 0x3f3f3f3f;
 24 const int mod = 1e9+7;
 25 const int maxn = 10000+10;
 26 int c[maxn];
 27 struct qnode {
 28     int v;
 29     LL c;
 30     qnode(int _v=0, LL _c =0):v(_v), c(_c) {}
 31     bool operator < (const qnode &r) const {
 32         return c > r.c;
 33     }
 34 };
 35 struct Edge {
 36     int v, cost;
 37     Edge(int _v=0, int _cost =0):v(_v), cost(_cost) {}
 38 };
 39 vector <Edge> E[10*maxn];
 40 bool vis[maxn];
 41 LL dist[maxn];
 42 void Dij(int n, int start) {
 43     memset(vis,false,sizeof(vis));
 44     for(int i=1; i<=n; i++)dist[i]=INF;
 45     priority_queue<qnode>que;
 46     while(!que.empty())que.pop();
 47     dist[start]=0;
 48     que.push(qnode(start,0));
 49     qnode tmp;
 50     while(!que.empty()) {
 51         tmp=que.top();
 52         que.pop();
 53         int u=tmp.v;
 54         if(vis[u])continue;
 55         vis[u]=true;
 56         for(int i=0; i<E[u].size(); i++) {
 57             int v=E[tmp.v][i].v;
 58             int cost=E[u][i].cost;
 59             if(!vis[v]&&dist[v]>dist[u]+cost) {
 60                 dist[v]=dist[u]+cost;
 61                 que.push(qnode(v,dist[v]));
 62             }
 63         }
 64     }
 65 }
 66 void addedge(int u, int v, int w) {
 67     E[u].pb(Edge(v, w));
 68 }
 69 vector<pair<int, int> > One;
 70 void solve() {
 71     int n, m, x, a, b;
 72     scanf("%d%d", &n, &m);
 73     for(int i = 1; i<=n; i++) {
 74         scanf("%d", &c[i]);
 75         addedge(0, i, c[i]);//0指向物品i,表示直接购买的花费
 76     }
 77     for(int i = 1; i<=m; i++) {
 78         scanf("%d%d%d", &x, &a, &b);
 79         addedge(a, x, c[b]);//a指向物品x,表示需要在花费c[b]的花费就可以合成x
 80         addedge(b, x, c[a]);
 81         if(x==1){//记录一下物品1的合成
 82             One.pb(mp(a, b));
 83         }
 84     }
 85     Dij(n, 0);
 86     LL ans = dist[1];//得到1的花费
 87     for(int i = 0;i<One.size();i++){
 88         ans = min(ans, dist[One[i].first]+dist[One[i].second]);//和通过合成的花费比较
 89     }
 90     printf("%lld\n", ans);
 91 }
 92 int main() {
 93 #ifdef LOCAL
 94     freopen("input.txt", "r", stdin);
 95 //        freopen("output.txt", "w", stdout);
 96 #endif
 97     freopen("dwarf.in", "r", stdin);
 98     freopen("dwarf.out", "w", stdout);
 99     solve();
100     return 0;
101 }

时间: 2024-10-08 07:58:54

Codeforces Gym 100269 Dwarf Tower (最短路)的相关文章

HNU 12847 Dwarf Tower(最短路+队列优化)

题目链接:http://acm.hnu.cn/online/?action=problem&type=show&id=12847 解题报告:有n样物品,编号从1到n第i样物品可以通过金币vi买到,同时有m种方法,方法的内容是由两种物品可以构造出另一种物品,现在要你求出得到1物品的价值最小是多少? 当成最短路来解,用邻接表存好m种构造方法,然后用队列里面的点去尝试通过构造的方法使得得到i物品所花的价值更小,如果更新成功,再把更新成功的那个点又加入到队列中. 同时要标记一下这个点是不是正在队列

Problem D. Dwarf Tower spfa

http://codeforces.com/gym/100269/attachments 首先建图,然后图中每条边的权值是会变化的,是由dis[x] + dis[y]  --->   dis[make],然后就相当于新增加一个原点0,求0到1的最短距离 #include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef

Codeforces gym Hello 2015 Div1 B and Div2 D

Codeforces gym 100571 problem D Problem 给一个有向图G<V,E>和源点S,边的属性有长度L和颜色C,即E=<L,C>.进行Q次询问,每次给定一个点X,输出S到X的最短路的长度(不存在则输出 -1).但要求S到X的路径中相邻两条边颜色不一样. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 |V|, |E|: [1, 10^5] X, S: [1, |V| ] L: [1, 10^9] |C|

Dwarf Tower

dwarf tower (dwarf.cpp/c/pas)[问题描述]Vasya在玩一个叫做"Dwarf Tower"的游戏,这个游戏中有n个不同的物品,它们的编号为1到n.现在Vasya想得到编号为1的物品.获得一个物品有两种方式:1. 直接购买该物品,第i件物品花费的钱为ci2. 用两件其他物品合成所需的物品,一共有m种合成方式.请帮助Vasya用最少的钱获得编号为1的物品. [输入格式]第一行有两个整数n,m(1<=n<=10000,0<=m<=10000

Codeforces gym Hello 2015 Div1 E

Codeforces gym 100570 problem E (一种处理动态最长回文子串问题的方法) Problem 给一个长度为N的字符串S,字符集是'a'-'z'.进行Q次操作,操作分三种.一,修改位置X的字符为C:二,查询以P位置为中心的最长回文子串的长度,并输出:三,查询以P与P+1的中间位置为中心的最长回文子串的长度,并输出. More 第二种操作子串长度为奇数,一定存在:第三种操作子串长度为偶数,若不存在,输出 -1. Limits Time Limit(ms): 4000(1s足

Codeforces gym Hello 2015 Div1 C and Div2 E

Codeforces gym 100570 problem C Codeforces gym 100571 problem E Problem 给一个N行M列的矩阵Ma,进行Q次(Q<=10)查询,每次给定一个K,问有多少子矩阵,满足最大值max - 最小值min <=K. Limits Time Limit(ms): 8000 Memory Limit(MB): 512 N, M: [1, 400] Q: [1, 10] Ma(i, j), K: [1, 10^9] Solution (Th

[HNU4]Dwarf Tower

题意:给你n件物品,每个物品买需要一个价值,m个规则 x,y,z  表示 y z 可以构成 x  ,问你最少要多少构成第一个物品, 解题思路:这里用到图论思想,每有一个点更新就把它加入到队列里面等待松弛,但是还是必须要标记 解题代码: 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream>

【模拟】ECNA 2015 I What&#39;s on the Grille? (Codeforces GYM 100825)

题目链接: http://codeforces.com/gym/100825 题目大意: 栅栏密码.给定N(N<=10),密钥为一个N*N的矩阵,'.'代表空格可以看到,'X'代表被遮挡,还有密文字符串S,长度为N*N 每次将这个矩阵顺时针旋转90°,把矩阵中空格对应的位置按照从上到下从左到右的顺序依次填充上密文字符,求最终这个密文字符能否填满N*N的矩阵,能按顺序输出得到的答案,不能输出"invalid grille" 题目思路: [模拟] 直接模拟即可.旋转的坐标公式很好推.

Codeforces gym Hello 2015 Div2 B

Codeforces gym 100571 problem B Problem 设函数F(x),F(1)与F(2)已知,且当 i>=3,F(i)=a*F(i-2)+b*F(i-1).再给一个长度为N的数列A,进行Q次如下操作:每次给一个区间[L, R],对于每个k(L=<k<=R),将A[k]=A[k]+F[k-L+1].最后输出数列A(mod 10^9+7). Limits Time Limit(ms): 1000 Memory Limit(MB): 256 N, Q: [1, 10^