【并查集】/*
Program : NOIP2015 TG D1T2 message
Way : 1,Delete Points & Lines
Input : Files,"message.in"
Output : Files,"message.out"
*/
# include <queue>
# include <cstdio>
using namespace std;
const int MAXN = 200010;
const int INF = 10000000;
int next[MAXN];
int in_n[MAXN];
bool visited[MAXN];
int n;
int MinLen = INF;
queue<int> Q;
void Delete_in_0(){
for (int i=0;i<n;++i) if (in_n[i] == 0) Q.push(i);
while (!Q.empty()){
visited[Q.front()] = true;
--in_n[next[Q.front()]];
if (in_n[next[Q.front()]] == 0) Q.push(next[Q.front()]);
Q.pop();
}
}
int Round_Len(int pos){
int len = 0;
while (!visited[pos]){
visited[pos] = true;
pos = next[pos];
++len;
}
return len;
}
inline int min(int a,int b){ return a < b ? a : b; }
int main(){
freopen("message.in","r",stdin);
freopen("message.out","w",stdout);
scanf("%d",&n);
for (int i=0;i<n;++i){
scanf("%d",&next[i]);
--next[i];
++in_n[next[i]];
}
Delete_in_0();
for (int i=0;i<n;++i){
if (!visited[i]){
MinLen = min(MinLen,Round_Len(i));
}
}
printf("%d\n",MinLen);
return 0;
}
【时间戳】/*
Program : NOIP2015 TG D1T2 message
Way : 2,Union-Find Set
Input : Files,"message.in"
Output : Files,"message.out"
*/
# include <cstdio>
using namespace std;
const int MAXN = 200010;
const int INF = 10000000;
int father[MAXN];
int size[MAXN];
int findroot(int x){
// printf("%d\n",x);
return father[x] = (father[x] == x ? x : findroot(father[x]));
}
void merge(int a,int b){
if (findroot(a) == findroot(b)) return;
int sizea = size[findroot(a)];
int sizeb = size[findroot(b)];
if (sizea < sizeb){
father[findroot(a)] = findroot(b);
size[findroot(b)] += sizea;
}
else{
father[findroot(b)] = findroot(a);
size[findroot(a)] += sizeb;
}
}
int n;
int next[MAXN];
bool visited[MAXN];
int RoundLen(int pos){
int len = 0;
while (!visited[pos]){
visited[pos] = true;
pos = next[pos];
++len;
}
return len;
}
int MinLen = INF;
inline int min(int a,int b){ return a < b ? a : b; }
int main(){
freopen("message.in","r",stdin);
freopen("message.out","w",stdout);
scanf("%d",&n);
for (int i=0;i<n;++i) { size[i] = 1; father[i] = i; }
for (int i=0;i<n;++i){
scanf("%d",&next[i]); --next[i];
if (findroot(i) == findroot(next[i]) && !visited[i] && !visited[next[i]]){
MinLen = min(MinLen,RoundLen(i));
}
merge(i,next[i]);
}
printf("%d\n",MinLen);
}
【总结】/*
Program : NOIP2015 TG D1T2 message
Way : 3,Time Signs
Input : Files,"message.in"
Output : Files,"message.out"
*/
# include <cstdio>
using namespace std;
const int MAXN = 200010;
const int INF = 10000000;
int t = 1;
int ttime = 0;
int next[MAXN];
int time[MAXN];
int turn[MAXN];
int RoundLen(int x){
++ttime;
time[x] = t;
turn[x] = ttime;
while (time[next[x]] == 0){
++t;
x = next[x];
time[x] = t;
turn[x] = ttime;
}
if (ttime == turn[next[x]])
return time[x] - time[next[x]] + 1;
else
return INF;
}
inline int min(int a,int b){ return a < b ? a : b; }
int n;
int MinLen = INF;
int main(){
freopen("message.in","r",stdin);
freopen("message.out","w",stdout);
scanf("%d",&n);
for (int i=0;i<n;++i){ scanf("%d",&next[i]); --next[i]; }
for (int i=0;i<n;++i){
if (time[i] == 0) MinLen = min(MinLen,RoundLen(i));
}
printf("%d\n",MinLen);
return 0;
}