觉得自己这两天都很颓T_T (难题不会做简单题不想做QWQ)
那么这个就是一个乱搞,为什么选择做这道题呢,是因为我也不知道
这个就是一个内向树森林嘛。
那么对于最大值,就只有叶子打不死咯,假如是简单环就少死一个咯
最小值很麻烦的说。。叶子也是打不死,那么它上面那个就得死,没死的打死上面的,由此类推,环也是类似思想,就是实现麻烦。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct node { int x,y,next; }a[2100000];int len,last[1100000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } vector<int>h; int z,ys[1100000],fa[1100000]; bool v[1100000]; void findhuan(int x) { ys[x]=++z; if(v[x]==true)h.push_back(x); for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(ys[y]==0) { fa[y]=x; findhuan(y); } } for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(ys[y]>ys[x]&&fa[y]!=x) { h.push_back(y);v[y]=true; do { y=fa[y];v[y]=true; h.push_back(y); }while(y!=x); } } } int mmin,cc,tot[1100000];bool bekilled[1100000]; int dfs(int x,int fr,bool bk) { tot[x]=1; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(v[y]==false&&y!=fr) { bk=true; dfs(y,x,false); tot[x]+=tot[y]; } } if(bk==false)cc++; if(bekilled[x]==false&&fr!=-1) { if(bekilled[fr]==false) { mmin++; bekilled[fr]=true; } } } int c[1100000]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n; n=read(); len=0;memset(last,0,sizeof(last)); memset(v,false,sizeof(v)); for(int i=1;i<=n;i++) { c[i]=read(); ins(i,c[i]);ins(c[i],i); if(c[c[i]]==i)v[i]=v[c[i]]=true; } z=0;int mmax=0;mmin=0; memset(bekilled,false,sizeof(bekilled)); for(int i=1;i<=n;i++) { if(ys[i]==0) { h.clear(); fa[i]=i;findhuan(i); int leaf=0,stot=0; for(int j=0;j<h.size();j++) { int k=h[j]; cc=0;dfs(k,-1,true); stot+=tot[k]; leaf+=cc; } if(leaf==0&&stot!=1)leaf=1; mmax+=stot-leaf; if(h.size()==1&&bekilled[h[0]]==false)mmin++; else if(h.size()==2) { if(!(bekilled[h[0]]|bekilled[h[1]]))mmin++; } else { int H=h.size();bool ay=false; for(int j=0;j<H;j++) if(bekilled[h[j]])ay=true; if(ay==false)mmin+=(h.size()+1)/2; else { int zz=2; while(zz--) { for(int j=0;j<H;j++) { if(bekilled[h[j]]&&!bekilled[h[(j+1)%H]]&&!bekilled[h[(j+2)%H]]) { bekilled[h[(j+2)%H]]=true;mmin++; } } } } } } } printf("%d %d\n",mmin,mmax); return 0; }