[关闭]
@Junlier 2018-10-31T19:18:58.000000Z 字数 1600 阅读 1661

洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

题解
阅读体验:https://zybuluo.com/Junlier/note/1311990
原题地址:洛谷P1155 双栈排序

很好的一道图论模型转化的题目
考虑什么情况下两个元素一定要放在不同的栈内
经过一番仔细思考+草稿模拟你会得出

当且仅当存在三元组,其中时,一定要放在两个不同的栈内

抽象理解一下,如果放在同一个栈内,后面还有一个比都小的,那么两个栈内元素都是递增的了,无论如何也排不好序了
那么根据这个建出一个图(转化模型)
当存在上面的情况时,在间连一条边,表示要在不同的栈内
就可以跑二分图染色判断合法性了,然后染完色根据题目模拟即可

题目还是很好的,多掌握一点题型就少一点措手不及

  1. #include<bits/stdc++.h>
  2. #define il inline
  3. #define rg register
  4. #define ldb double
  5. #define lst long long
  6. #define rgt register int
  7. #define N 1050
  8. #define M 1000050
  9. #define qw ljl[i].to
  10. using namespace std;
  11. const int Inf=1e9;
  12. il int MAX(rgt x,rgt y){return x>y?x:y;}
  13. il int MIN(rgt x,rgt y){return x<y?x:y;}
  14. il int read()
  15. {
  16. int s=0,m=0;char ch=getchar();
  17. while(!isdigit(ch)){if(ch=='-')m=1;ch=getchar();}
  18. while( isdigit(ch))s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
  19. return m?-s:s;
  20. }
  21. int n;
  22. int v[N],Min[N];
  23. stack<int> st1,st2;
  24. int hd[N],vis[N],col[N],cnt;
  25. struct EDGE{int to,nxt;}ljl[M<<1];
  26. il void Add(rgt p,rgt q){ljl[++cnt]=(EDGE){q,hd[p]},hd[p]=cnt;}
  27. void Dfs(rgt now,rgt C)
  28. {
  29. vis[now]=1,col[now]=C;
  30. for(rgt i=hd[now];i;i=ljl[i].nxt)
  31. {
  32. if(vis[qw])
  33. {
  34. if(col[qw]==C)puts("0"),exit(0);
  35. continue;
  36. }Dfs(qw,C^1);
  37. }
  38. }
  39. int main()
  40. {
  41. n=read(),Min[n+1]=Inf;
  42. for(rgt i=1;i<=n;++i)v[i]=read();
  43. for(rgt i=n;i>=1;--i)Min[i]=MIN(Min[i+1],v[i]);
  44. for(rgt i=1;i<n;++i)
  45. for(rgt j=i+1;j<=n;++j)
  46. if(v[i]<v[j]&&Min[j+1]<v[i])
  47. Add(i,j),Add(j,i);
  48. for(rgt i=1;i<=n;++i)if(!vis[i])Dfs(i,0);
  49. rgt wnt=1;
  50. for(rgt i=1;i<=n;++i)
  51. {
  52. if(col[i])st2.push(v[i]),printf("c ");
  53. else st1.push(v[i]),printf("a ");
  54. while((!st1.empty()&&st1.top()==wnt)||(!st2.empty()&&st2.top()==wnt))
  55. {
  56. if(!st1.empty()&&st1.top()==wnt)st1.pop(),printf("b ");
  57. else st2.pop(),printf("d ");++wnt;
  58. }
  59. }return puts(""),0;
  60. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注