P4042 [AHOI2014/JSOI2014]骑士游戏(有向有环不可缩点)

Lisa

显然会形成一个图的结构,显然这玩意极有可能出现环

那咋办呢

从每一怪兽出发似乎都可以形成一个子问题。

每一个问题都是用自己所能到达的怪兽的花费来更新自己,如果自己更新了,就有机会更新自己的父亲

显然不会一直更新下去,这个环是有极限的。

所以好像出现了一个类似于spfa的结构

就是首先每个点的花费就是他自己法术攻击,然后利用普通攻击更新上面的过程

怎么知道第一次更新谁呢,不知道,那就全扔进去就可以了

跑啊跑,直到无可更新

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#define int long long
using namespace std;
int n;
int a[200105];
vector<int> fr[200105],to[200105];
int x,y,z;
queue<int> q;
int dis[200105];
int vis[200105];
void spfa(){
	while(!q.empty()){
		int x=q.front();
		vis[x]=0;
		q.pop();
		int tem=a[x];
		for(int i=0;i<to[x].size();++i){
			tem+=dis[to[x][i]];
		}
		if(tem<dis[x]){
			dis[x]=tem;
			for(int i=0;i<fr[x].size();++i){
				if(!vis[fr[x][i]]){
					vis[fr[x][i]]=1;
					q.push(fr[x][i]);
				}
			}
		}
	}
}
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld%lld%lld",&a[i],&dis[i],&x);
		q.push(i);
		vis[i]=1;
		for(int j=1;j<=x;++j){
			scanf("%lld",&y);
			to[i].push_back(y);
			fr[y].push_back(i);
		}
	}
	spfa();
	cout<<dis[1];
	return 0;
}
原文地址:https://www.cnblogs.com/For-Miku/p/15120977.html