信息传递--NOIP2015 day1 T2--暴力
这道题我用了判联通量加暴力,但联通量判炸了。。。。然后从code[VS]上看到个不错的代码,就拿来了^_^...
基本思路是去掉环外的点,然后走每一个联通块。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 int n,fa[200001],x[200001],ru[200001],g[200001]; 8 bool w[200001]; 9 //fa记录当前节点的传递目标,x记录每个环中每个点的长度 10 //ru记录每个点的入度,g记录每个环中的最终长度 11 12 13 //快速读入 14 int getint() 15 { 16 int w=0,q=0; 17 char c=getchar(); 18 while ((c>'9'||c<'0')&&c!='-') 19 c=getchar(); 20 if (c=='-') q=1,c=getchar(); 21 while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); 22 return q?-w:w; 23 } 24 25 //删除当前点,如果他的下一个点也只有一个入度,那么递归删除 26 void shan(int k) 27 { 28 w[k]=1; 29 ru[fa[k]]--; 30 if(ru[fa[k]]==0) 31 shan(fa[k]); 32 } 33 34 int main() 35 { 36 n=getint(); 37 for (int i=1; i<=n; i++) 38 fa[i]=getint(),ru[fa[i]]++; //读入 39 40 for (int i=1; i<=n; i++) 41 if(ru[i]==0&&!w[i]) //如果当前点只有一个入度 42 shan(i); //调用删除程序 43 44 for (int i=1; i<=n; i++) 45 if(!w[i]) //如果i没被删除 46 { 47 x[1]=fa[i]; 48 int y=fa[i],ans=1; 49 while (i!=y) //当环没有找到终点时 50 w[y]=1,y=fa[y],x[++ans]=y; //递推 51 for (int j=1; j<=ans; j++) 52 g[x[j]]=ans; //用g[最后一个点]记录最后的距离 53 } 54 55 int ans=0x7fffffff; 56 for (int i=1;i<=n;i++) 57 if(!w[i]) //如果m未被删除 58 ans=min(ans,g[i]); //取最小值 59 printf("%d",ans); 60 }
附DFS一个
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int MAXN = 200005; int n; int fa[MAXN]; int dfn[MAXN]; int vis[MAXN], vi = 0;; int ans = 0x3f3f3f3f; void dfs(int x, int df) { vis[x] = vi; dfn[x] = df; int nex = fa[x]; if (!vis[nex]) dfs(nex, df + 1); else if (vis[nex] && vis[nex] != vi) return; else if (vis[nex] == vi) { ans = min(ans, df - dfn[nex] + 1); return; } } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &fa[i]); } for (int i = 1; i <= n; i++) { if (!vis[i]) { vi++; dfs(i, 1); } } cout << ans << endl; return 0; }