题意:给你一个数组,然后给你主角在数组中的位置, 每个位置是一个非负整数,表示数组中这个人的前面的人的数组序号是多少(0代表不记得前面是谁),问你主角有可能在队列的什么位置。
解题思路:并查集 + 0/1背包。可以把一条一条链看成物品。
解题代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // File Name: 316b2.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月22日 星期日 14时58分34秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 #define maxn 1005 26 using namespace std; 27 int fa[maxn]; 28 int site ; 29 int color; 30 int find(int x) 31 { 32 fa[x] == x?x:fa[x] = find(fa[x]); 33 } 34 void dfs(int x ,int dis) 35 { 36 if(fa[x] == x) 37 { 38 color = x; 39 site = dis; 40 return; 41 } 42 dfs(fa[x],dis + 1); 43 } 44 int tt ; 45 int hs[10005]; 46 int a[1005]; 47 int dp[1050][1050]; 48 int main(){ 49 int n , x; 50 scanf("%d %d",&n,&x); 51 for(int i = 1;i <= n;i ++) 52 { 53 scanf("%d",&fa[i]); 54 if(fa[i] == 0) 55 fa[i] = i; 56 } 57 dfs(x,1); 58 for(int i = 1 ;i <= n;i ++) 59 { 60 find(i); 61 } 62 for(int i = 1;i <= n;i ++) 63 { 64 if(fa[i] != color) 65 hs[fa[i]] ++; 66 } 67 tt = 0 ; 68 for(int i = 1;i <= n;i ++) 69 { 70 if(hs[i] != 0 ) 71 { 72 tt ++ ; 73 a[tt] = hs[i]; 74 } 75 } 76 memset(dp,0,sizeof(dp)); 77 dp[0][0] = 1; 78 for(int i = 1;i <= tt;i ++) 79 { 80 for(int j =0 ;j <= n;j ++) 81 { 82 if(dp[i-1][j] == 1 ) 83 { 84 dp[i][j] = 1; 85 dp[i][j+a[i]] = 1; 86 } 87 } 88 } 89 for(int i = 0 ;i <= n;i ++) 90 { 91 if(dp[tt][i] == 1) 92 printf("%d ",i+site); 93 } 94 95 return 0; 96 }