好啦!!近十年题目最后一道黄题啦!!
用并查集求最小环,并不是很难的一道题
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int f[200002],d[200002],n,minn,last; //f保存祖先节点,d保存到其祖先节点的路径长。 5 int fa(int x) 6 { 7 if (f[x]!=x) //查找时沿途更新祖先节点和路径长。 8 { 9 int last=f[x]; //记录父节点(会在递归中被更新)。 10 f[x]=fa(f[x]); //更新祖先节点。 11 d[x]+=d[last]; //更新路径长(原来连在父节点上)。 12 } 13 return f[x]; 14 } 15 void check(int a,int b) 16 { 17 int x=fa(a),y=fa(b); //查找祖先节点。 18 if (x!=y) {f[x]=y; d[a]=d[b]+1;} //若不相连,则连接两点,更新父节点和路径长。 19 else minn=min(minn,d[a]+d[b]+1); //若已连接,则更新最小环长度。 20 return; 21 } 22 int main() 23 { 24 int i,t; 25 scanf("%d",&n); 26 for (i=1;i<=n;i++) f[i]=i; //祖先节点初始化为自己,路径长为0。 27 minn=0x7777777; 28 for (i=1;i<=n;i++) 29 { 30 scanf("%d",&t); 31 check(i,t); //检查当前两点是否已有边相连接。 32 } 33 printf("%d",minn); 34 return 0; 35 }