BZOJ3875-[Ahoi2014&Jsoi2014]騎士遊戲
阿新 • • 發佈:2019-02-20
題解:
我們可以令表示殺死i怪獸的最小代價。
,為受到物理攻擊後分裂成的所有怪獸。
我們發現直接是有後效性的,我們可以用來做這個。
用兩個陣列每次更新差值就好了。
#include<bits/stdc++.h>
#define ll long long
#define N 300005
using namespace std;
struct edge
{
int vet,next;
}edge[N<<2 ];
int head[N],tot=0;
void add_edge(int u,int v)
{
edge[++tot].vet=v;
edge[tot].next=head[u];
head[u]=tot;
}
vector<int>vet[N];
ll f[N],s[N],vis[N];
int n,r;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&s[i],&f[i]);
int w;
scanf("%d",&w);
for(int j=1;j<=w;j++)
{
int r;
scanf("%d",&r);
add_edge(i,r);
vet[r].push_back(i);
}
}
queue<int>Q;
for(int i=1;i<=n;i++)
{
Q.push(i);
vis[i]=1;
}
while (!Q.empty())
{
int u=Q.front();
Q.pop();
vis[u]=0;
ll tmp=s[u];
for(int i=head[u];i;i=edge[i].next)
tmp+=f[edge[i].vet];
if(tmp>=f[u])continue;
f[u]=tmp;
for(int i=0;i<vet[u].size();i++)
if(!vis[vet[u][i]])
{
vis[vet[u][i]]=1;
Q.push(vet[u][i]);
}
}
printf("%lld\n",f[1]);
return 0;
}