1124: [POI2008]枪战Maf
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 654 Solved: 258
[Submit][Status][Discuss]
Description
有n个人,每个人手里有一把手枪。一开始所有人都选定一个人瞄准(有可能瞄准自己)。然后他们按某个顺序开枪,且任意时刻只有一个人开枪。因此,对于不同的开枪顺序,最后死的人也不同。
Input
输入n人数<1000000 每个人的aim
Output
你要求最后死亡数目的最小和最大可能
Sample Input
8
2 3 2 2 6 7 8 5
2 3 2 2 6 7 8 5
Sample Output
3 5
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int N=1000005;
int ans1,ans2;
int n,a[N],du[N],q[N],len;
bool die[N],undie[N],flag;
int main (){
scanf ("%d",&n);
for (int i=1;i<=n;++i){
scanf ("%d",&a[i]);
du[a[i]]++;
}
for (int i=1;i<=n;++i)
if (du[i]==0)q[ans1=++ans2]=i;
for (int i=1;i<=ans1;++i){
int ne=a[q[i]];
if (die[ne])continue;
if (!(du[a[ne]]-=(die[ne]=undie[a[ne]]=1)))q[++ans1]=a[ne];
}
for (int i=1;i<=n;++i)
if (!die[i] && du[i]){
len=flag=0;
for (int j=i;!die[j];j=a[j]){
die[j]=1;len++;flag|=undie[j];
}
if (!flag && len>1)ans2++;
ans1+=len/2;
}
printf ("%d %d",n-ans1,n-ans2);
return 0;
}