题意:在dota游戏中,有些物品可以直接通过金钱购买,一些高级道具无法直接购买,只能通过购买的合成获得,现在给一些能够购买的物品及其对应价格,并有告知已经拥有的物品及数量,给定一些道具的合成公式,及想要获得的物品及数量。问需要花多少钱.
直接构图,给每个物品一个编号,逆向建图,从底层求起,直到获得高级道具的价格.
#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
#include<string>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 200;
map<string,int> m;
struct Equ
{
int num;
int price;
string name;
}equ[maxn];
vector<int> g[maxn];
int c=0;
int Find(string s)
{
for(int i=0;i<c;i++)
{
if(equ[i].name==s)
return i;
}
equ[c].name=s;
equ[c].num=0;
equ[c++].price=0;
return c-1;
}
int dfs(int u,int num)
{
int ans=0,a=0;
if(equ[u].num!=0)
{
if(equ[u].num>=num)
{
equ[u].num-=num;
return 0;
}
else
{
num-=equ[u].num;
equ[u].num=0;
}
}
for(int i=0;i<g[u].size();i++)
{
int v = g[u][i];
a=dfs(v,num);
ans+=a;
}
if(g[u].size()==0)
{
if(num>=equ[u].num)
{
ans=(num-equ[u].num)*equ[u].price;
equ[u].num=0;
}
else
{
equ[u].num-=num;
}
}
return ans;
}
int main()
{
string name;
int n,k,flag,pos;
queue<int> q;
while(cin>>n)
{
for(int i=0;i<c;i++)
g[i].clear();
while(!q.empty())q.pop();
c=n;
int p;
for(int i=0;i<n;i++)
{
cin>>name>>p;
equ[i].name=name;
equ[i].num=0;
equ[i].price=p;
}
cin>>n;
for(int i=0;i<n;i++)
{
pos=-1;
cin>>name>>p;
for(int j=0;j<c;j++)
{
if(equ[j].name==name)
{
pos=j;
}
}
if(pos==-1)
{
equ[c].name=name;
equ[c].num=p;
equ[c++].price=(1<<30);
}
else
{
equ[pos].num=p;
}
}
cin>>n;
for(int i=0;i<n;i++)
{
cin>>name;
q.push(Find(name));
while(cin>>name&&name!="=")
{
if(name=="+")continue;
q.push(Find(name));
}
cin>>name;
int u=Find(name);
while(!q.empty())
{
int v = q.front();q.pop();
g[u].push_back(v);
}
}
cin>>n;
int ans=0;
for(int i=0;i<n;i++)
{
cin>>name>>p;
ans+=dfs(Find(name),p);
}
printf("%d\n",ans);
}
}