1. 程式人生 > 其它 >P4042 [AHOI2014/JSOI2014]騎士遊戲(有向有環不可縮點)

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;
}