cf 843 A Sorting by Subsequences [建图]

题面:

传送门

思路:

这道题乍一看有点难

但是实际上研究一番以后会发现,对于每一个位置只会有一个数要去那里,还有一个数要离开

那么只要把每个数和他将要去的那个位置连起来,构成了一个每个点只有一个入边一个出边的一张图

那么在这张图里的一个环,就代表着一个满足条件的子序列

所以只要把图建出来以后,统计图中的每一个环就可以了

Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 inline int read(){
 8     int re=0,flag=1;char ch=getchar();
 9     while(ch>'9'||ch<'0'){
10         if(ch=='-') flag=-1;
11         ch=getchar();
12     }
13     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
14     return re*flag;
15 }
16 int n,first[100010],cnt,tot;
17 bool vis[100010];
18 struct edge{
19     int to,next;
20 }a[200010];
21 struct node{
22     int val,num;
23 }x[100010];
24 priority_queue<int,vector<int>,greater<int> >q[100010];
25 bool cmp(node l,node r){
26     return l.val<r.val;
27 }
28 inline void add(int u,int v){
29 //    cout<<u<<ends<<v<<endl;
30     a[++cnt]=(edge){v,first[u]};first[u]=cnt;
31 }
32 void dfs(int u,int now){
33 //    cout<<"dfs "<<u<<ends<<now<<endl;
34     vis[u]=1;q[now].push(u);
35     int i,v;
36     for(i=first[u];~i;i=a[i].next){
37         v=a[i].to;
38         if(vis[v]) return;
39         dfs(v,now);
40     }
41 }
42 int main(){
43     memset(first,-1,sizeof(first));
44     int i,j;
45     n=read();
46     for(i=1;i<=n;i++){
47         x[i].val=read();x[i].num=i;
48     }
49     sort(x+1,x+n+1,cmp);
50     for(i=1;i<=n;i++){
51         add(i,x[i].num);
52     }
53     for(i=1;i<=n;i++){
54         if(!vis[i]) dfs(i,++tot);
55     }
56     printf("%d
",tot);
57     for(i=1;i<=tot;i++){
58         printf("%d",q[i].size());
59         while(!q[i].empty()) printf(" %d",q[i].top()),q[i].pop();
60         printf("
");
61     }
62 }
原文地址:https://www.cnblogs.com/dedicatus545/p/8455281.html