魔方俱乐部
魔方俱乐部
题解
我们根据题目可得这道题的图只有环与连在环上的链两种情况,我们分别处理两种情况即可。
源码
#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;
}

浙公网安备 33010602011771号