05年的題,然而我卻不會作c++
好多題解都沒有證實爲何若是有m我的位置錯誤,只需花費m的代價就能夠將其變爲正確,我來證實一下spa
這m我的能夠當作一個錯排,每一個人都有其應該在的位置p[i],從i向p[i]連一條邊,則整張圖中至少有一個環code
由於對於每一個點i,顯然有一條出邊和入邊,故全部點都在環上,故只需把這個環總體移動一次get
大佬都是直接模擬建圖,只有我很是垃圾地用了dfs判基環的方法,代碼又臭又長input
咱們的目標是找到一個x,使得整個環右移x位後,在目標位置的人最多it
環能夠反着看,所以須要把目標位置reverse一下再作一次class
#include<bits/stdc++.h> using namespace std; #define go(i,a,b) for(int i=a;i<=b;++i) #define com(i,a,b) for(int i=a;i>=b;--i) #define mem(a,b) memset(a,b,sizeof(a)) #define fo(i,a) for(int i=0;i<a;++i) #define il inline const int inf=0x3f3f3f3f,N=5e4+10; int n,p[N],s[N],top=0,tot,head[N],cnt; int c1[N],c2[N],mx; bool vis[N]; struct edge{ int nxt,v; }e[N*2]; void add(int u,int v){ e[cnt]=(edge){head[u],v}; head[u]=cnt++; } il void read(int &x){ x=0;char c=getchar(),f=1; while(c<'0'||c>'9'){ c=='-'?f=-1:0; c=getchar(); } while(c>='0'&&c<='9'){ x=x*10+c-'0'; c=getchar(); } x*=f; } il void fail(){ puts("-1");exit(0); } bool dfs(int u,int fa){ if(vis[u]){ int x; do{ x=s[top--]; p[++tot]=x; }while(x!=u&&top); if(tot!=n) fail(); else return 1; } vis[u]=1; s[++top]=u; for(int i=head[u];i+1;i=e[i].nxt){ int v=e[i].v; if(v==fa) continue; if(dfs(v,u)) return 1; } --top; return 0; } int main(){ //freopen("input.txt","r",stdin); //freopen("out.txt","w",stdout); mem(head,-1); read(n); int x,y; go(i,1,n){ read(x),read(y); add(i,x),add(i,y); } dfs(1,0); go(i,1,n){ mx=max(mx,++c1[(p[i]-i+n)%n]); mx=max(mx,++c2[(i-(n-p[i]+1)+n)%n]); } cout<<n-mx; return 0; }