记录编号 432148 评测结果 AAAAAAAAAA
题目名称 膜法师 最终得分 100
用户昵称 Gravatar하루Kiev 是否通过 通过
代码语言 C++ 运行时间 0.469 s
提交时间 2017-08-02 21:32:05 内存使用 15.57 MiB
显示代码纯文本
#include <stdio.h>
#include <deque>
#define maxn 1000005
using namespace std;
int n,aim[maxn],ru[maxn],maxx,minn,yes[maxn],no[maxn];
deque<int> q;
void push_ru_0(){
     for(int i=1;i<=n;i++)
        if(!ru[i]){
          minn++;maxx++;    
          q.push_back(i);
        }
}
void kill_(){
     for(int i=1;i<=minn;i++){
        int k=aim[q.front()];
        q.pop_front();
        if(yes[k]) continue;
        yes[k]=1;//之后他打死一个人后
        no[aim[k]]=1;
        ru[aim[k]]--;
        if(ru[aim[k]]==0){//看那个人要打的人是否变成了入度为零.
          q.push_back(aim[k]);//如果变成了入度为零那么继续进队。
          minn++;
        }
    }//最后整张图剩下了一堆环。
}
int main(){
	freopen("maf.in","r",stdin);// 原题[POI2008]枪战Maf
	freopen("maf.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&aim[i]);
        ru[aim[i]]++;
    }//首先入度为零的肯定死不了。
    push_ru_0();//然后我们将入度为0的推入队列。
    kill_(); 
    for(int i=1;i<=n;i++){
        if(ru[i]&&!yes[i]){
            int zz=i,lian=0;bool pd=0;
            while(!yes[zz]){
                  yes[zz]=1;zz=aim[zz];lian++;
                  if(no[zz]) pd=1;
            }
            if(!pd&&lian>1) maxx++;//没入度,活一个 
            minn+=lian/2;//没入度,活一半 
        }
    }
    printf("%d %d",n-minn,n-maxx);
}