题目大意:每个同学可以指定一个人,然后构成一个有向图。1-n次查询,从某个人开始并放入一个东西,然后循环,直到碰到一个人已经放过了,就输出。
思路:直接模拟就可以了,O(n^2) 但是O(n)也可以实现, 不是太懂大神的思路。
初始化ans[i] = i, 一个点能被输出的话就是 ans[i] = i (可以模拟一下),这个ans是如何算的呢。大神用了topo排序。 记录入度数,然后把入读为0放入队列,取出来然后连接点入度--, ans[i] = p[i] ( p[i] 是 i 指定的人 )直到队列为空。
O(n^2)代码:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include
O(n)代码:
1 #include2 #include 3 using namespace std; 4 const int maxn = 1000 + 10; 5 int p[maxn], ans[maxn], deg[maxn]; 6 7 int res(int i) { //比较神奇 也就是循环 8 return i == ans[i] ? i : res(p[i]); 9 }10 11 int main(int argc, char const *argv[])12 {13 int n;14 scanf("%d", &n);15 for(int i = 1; i <= n; i++) {16 scanf("%d", &p[i]);//每个点指定的点17 deg[p[i]]++;//入读++18 }19 queue q;20 for(int i = 1; i <= n; i++) { //初始化ans21 ans[i] = i;22 if(deg[i] == 0)//入度为0 进队列23 q.push(i);24 }25 while(!q.empty()){ //topo26 int u = q.front(); q.pop();27 deg[p[u]]--;28 ans[u] = p[u];//这里不是太懂(模拟一下比较好)29 if(deg[p[u]] == 0)30 q.push(p[u]);31 }32 for(int i = 1; i <= n; i++)33 printf("%d ", res(i));34 return 0;35 }