题目链接:2019河北省大学生程序设计竞赛 - 舔狗
看到这道题我想到了拓扑排序,每次找度少的贪心肯定最优。
进而想到直接用堆维护当前点的最小度即可。
不知道为什么比赛过的人这么少。。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10;
int n,a[N],deg[N],vis[N];
struct node{int x,p;};
bool operator < (node a,node b){return a.p>b.p;}
priority_queue<node> q;
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),deg[a[i]]++;
for(int i=1;i<=n;i++) q.push({i,deg[i]});
while(q.size()){
node u=q.top(); q.pop();
if(vis[u.x]||vis[a[u.x]]) continue;
n-=2; vis[u.x]=vis[a[u.x]]=1;
int now=a[a[u.x]]; deg[now]--;
q.push({now,deg[now]});
}
cout<<n;
return 0;
}