CF1027D Mouse Hunt題解
阿新 • • 發佈:2019-07-21
題目:
伯蘭州立大學的醫學部剛剛結束了招生活動。和以往一樣,約80%的申請人都是女生並且她們中的大多數人將在未來4年(真希望如此)住在大學宿舍裡。
宿舍樓裡有nn個房間和一隻老鼠!女孩們決定在一些房間裡設定捕鼠器來除掉這隻可怕的怪物。在ii號房間設定陷阱要花費c_ic
i
伯蘭幣。房間編號從11到nn。
要知道老鼠不是一直原地不動的,它不停地跑來跑去。如果tt秒時它在ii號房間,那麼它將在t+1t+1秒時跑到a_ia
i
號房間,但這期間不會跑到別的任何房間裡(i=a_ii=a
i
表示老鼠沒有離開原來的房間)。時間從00秒開始,一旦老鼠竄到了有捕鼠器的房間裡,這隻老鼠就會被抓住。
如果女孩們知道老鼠一開始在哪裡不就很容易嗎?不幸的是,情況不是這樣,老鼠在第00秒時可能會在從11到nn的任何一個房間內。
那麼女孩們最少要花多少錢設定捕鼠器,才能保證老鼠無論從哪個房間開始流竄最終都會被抓到?
分析:
stack解決
a向a[x]連邊
程式碼:
#include<cstdio>
#include<stack>
using namespace std;
int a[200005];
int cnt=0;
int vis[200005],c[200005];
int flag;
int tag;
stack<int>s;
void dfs(int x)
{
if(a[x]==0)
{
return ;
}
cnt++;
if(cnt>vis[x]&&vis[x])
{
flag=1;
tag=x;
a[x]=0;
vis[x]=0;
return ;
}
s.push(x);
vis[x]=cnt;
dfs(a[x]);
vis[x]=0;
a[x]=0;
}
int main()
{
int n;
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]);
}
int sum=0;
for(int i=1;i<=n;i++)
{
while(!s.empty())s.pop();
flag=0;
dfs(i);
if(flag)
{
int ans=2147483647;
if(!s.empty())
{
while(!s.empty()&&s.top()!=tag)
{
ans=min(ans,c[s.top()]);
s.pop();
}
if(!s.empty())
ans=min(ans,c[s.top()]);
sum+=ans;
}
}
}
printf("%d\n",sum);
return 0;
}