Codeforces1027D-Mouse Hunt
程序员文章站
2024-03-17 10:14:10
...
题解:
还是比较水的一道题
先找强连通分量缩点,然后把所有出度为0的强连通分量内的最小值相加就是答案
注意自环!
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200005
using namespace std;
int tot,head[N],n,c[N],a[N],low[N],dfn[N],mn[N],Q[N];
int flag[N],deep,color[N],top,sum,Head[N],Tot,out[N];
struct node
{
int vet,next;
}edge[N],Edge[N];
void add(int u,int v)
{
edge[++tot]=(node){v,head[u]};
head[u]=tot;
}
void Add(int u,int v)
{
Edge[++Tot]=(node){v,Head[u]};
Head[u]=Tot;
}
void tarjan(int u)
{
low[u]=dfn[u]=++deep;
Q[++top]=u;flag[u]=true;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].vet;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(flag[v])
low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u])
{
color[u]=++sum;
flag[u]=0;
while(Q[top]!=u)
{
flag[Q[top]]=false;
color[Q[top--]]=sum;
}
top--;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]!=i)add(i,a[i]);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
memset(mn,0x3f3f3f,sizeof(mn));
for(int i=1;i<=n;i++)
{
mn[color[i]]=min(mn[color[i]],c[i]);
if(color[i]!=color[a[i]]&&i!=a[i])
{
Add(color[i],color[a[i]]);
out[color[i]]++;
}
}
int ans=0;
for(int i=1;i<=sum;i++)
if(!out[i])ans+=mn[i];
printf("%d\n",ans);
return 0;
}
推荐阅读
-
Codeforces1027D-Mouse Hunt
-
POJ - 1066 Treasure Hunt 【线段规范相交】
-
Treasure Hunt POJ - 1066
-
POJ 1066 Treasure Hunt
-
Educational Codeforces Round 23#A. Treasure Hunt
-
计算几何——Treasure Hunt(线段相交)
-
Educational Codeforces Round 49 (Rated for Div. 2)-D. Mouse Hunt
-
POJ 1066--Treasure Hunt(判断线段相交)
-
[UVALive] - 5816 Dhaka 2011 H - Treasure Hunt
-
dijkstra——Job Hunt S(负环)