【bzoj 3037】創世紀

傳送門~

解題思路

貪心思想,首先建圖後每個入度爲零的點一定不選,瞎j8畫圖後發現如果一個點不選,它限制的點一定是選了最優。因爲每個點只有一個出度,選到最後一定剩若干個簡單環,大小爲n的環一定可以選n/2個點,然後統計答案就好了。
代碼:

#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<queue>
using namespace std;
queue<int>q;
int to[1000005],r[1000005],vis[1000005];
int n,ans,pans;
void dfs(int x){
    pans++;vis[x]=0;
    if(vis[to[x]]==-1) dfs(to[x]);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&to[i]);
        r[to[i]]++;vis[i]=-1;
    }
    for(int i=1;i<=n;i++)
    if(!r[i]) {q.push(i);vis[i]=0;}
    while(!q.empty()){
        int x=q.front();q.pop();
        if(vis[to[x]]!=-1) continue;
        r[to[x]]--;
        if(!vis[x] || !r[to[x]]){
            vis[to[x]]=vis[x]^1;
            q.push(to[x]);
        }
    }
    for(int i=1;i<=n;i++){
        if(vis[i]==1) ans++;
        else if(vis[i]==-1){
            pans=0;dfs(i);
            ans+=pans/2;
        }
    }
    printf("%d",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章