魔方俱乐部

魔方俱乐部

题解

我们根据题目可得这道题的图只有环与连在环上的链两种情况,我们分别处理两种情况即可。

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream> 
#include<algorithm>
#include<stack>
#include<vector>
#include<queue>
#include<stack>
#define MAXN 200005
using namespace std;
typedef long long LL;
int n,a[MAXN],f[MAXN];
int dis[MAXN],sumx[MAXN];
stack<int> s;
bool instack[MAXN],vis[MAXN];
#define gc() getchar()
template<typename _T>
inline void read(_T &x)
{
	_T f=1;x=0;char s=gc();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
	while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
	x*=f;
}
void dfs(int x)
{
	if(vis[x]) return ;
	if(instack[x])
	{
		int t,sum=0;
		vector<int> G;G.clear();
		do
		{
			t=s.top();
			s.pop();
			G.push_back(t);
			sum+=a[t];
			instack[t]=false;
		}while(t!=x);
		int siz=G.size();
		for(int i=0;i<siz;i++)
		{
			//printf("%d\n",G[i]);
			dis[G[i]]=sum,vis[G[i]]=true;
		}
		//puts("");
		return ;
	}//枚举环
	s.push(x);instack[x]=true;
	dfs(f[x]);instack[x]=false;
	if(vis[x]) return ;
	dis[x]=dis[f[x]]+a[x];vis[x]=true;//枚举链
	s.pop();
	return ;
}
int main()
{
	read(n);
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=1;i<=n;i++) read(f[i]);
	for(int i=1;i<=n;i++)
		if(!vis[i])
			dfs(i);
	for(int i=1;i<=n;i++)
		printf("%d\n",dis[i]);
	return 0;
}


 

谢谢!!! 

posted @ 2022-07-07 00:13  StaroForgin  阅读(34)  评论(0)    收藏  举报  来源