1. 程式人生 > >Codeforces Gym 100269 Dwarf Tower (最短路)

Codeforces Gym 100269 Dwarf Tower (最短路)

pair iostream printf sync part ret scribe first pan

題目連接:

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 }
View Code

Codeforces Gym 100269 Dwarf Tower (最短路)