10.12 考试 第三题 所驼门王的宝藏题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.12 考试 第三题 所驼门王的宝藏题解相关的知识,希望对你有一定的参考价值。

技术分享

技术分享

技术分享

技术分享

  这道题一开始看了一眼没读懂,然后就第二个打的这道题。当时第一反应是并查集裸题,然后打了一半才反应过来所有门都是单向的,果断弃坑。

  然后想到了tarjan缩点,然后记忆化搜索求最长链。然后惊喜的发现建边是一个大难题,先不说 自 由 门,只有横天门就够人受的了。于是乎,我将每一行与在那一行的点进行建边,列也是同理,然后就可以不用暴力搜索了。然而,数据貌似可以将这点卡到n^2,当时我想的是这题n^2可能被卡6个点,但是别的方法我暂时也没想出来,就先打一下吧,听天由命,然后就去处理 自 由 门。

  自 由 门我一开始是直接map保存,这样花的时间要比暴力(扫三行)要少一点。然后在打完所有后一算内存,1e6的map有点悬,还是时间换空间吧……

  打完之后生怕T掉,几乎把所有的min,max都换成了,比较,结果tarjan的时候大小比较比反了,然后调了半天,感觉自己菜爆了。

  交上去之后就开始等待命运审判,还好,出题人挺良心,没被卡到,然后就没有然后了。

技术分享
  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <queue>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <map>
  9 #define N 1000005
 10 #define M 100005
 11 using namespace std;
 12 int n,r,c;
 13 struct no
 14 {
 15     int x,y,op;
 16 }node[M];
 17 int a1[N],a2[N],b[M],zz1,zz2,zz3;
 18 struct ro
 19 {
 20     int to,next;
 21 }road1[M],road2[M],road3[N*5],road[N*5];
 22 void build3(int x,int y)
 23 {
 24     zz3++;
 25     road3[zz3].to=y;
 26     road3[zz3].next=b[x];
 27     b[x]=zz3;
 28 }
 29 void build1(int x,int y)
 30 {
 31     zz1++;
 32     road1[zz1].to=y;
 33     road1[zz1].next=a1[x];
 34     a1[x]=zz1;
 35 }
 36 void build2(int x,int y)
 37 {
 38     zz2++;
 39     road2[zz2].to=y;
 40     road2[zz2].next=a2[x];
 41     a2[x]=zz2;
 42 }
 43 bool rd[M],rd2[M];
 44 int bel[M],zz4,zz5,size[M],dfn[M],low[M],st[M],top;
 45 void tarjan(int x)
 46 {
 47     zz4++;
 48     dfn[x]=low[x]=zz4;
 49     top++;
 50     st[top]=x;
 51     rd[x]=rd2[x]=1;
 52     for(int i=b[x];i>0;i=road3[i].next)
 53     {
 54         int y=road3[i].to;
 55         if(!rd2[y])
 56         {
 57             tarjan(y);
 58             if(low[y]<low[x])low[x]=low[y];
 59         }
 60         else if(rd[y])
 61         {
 62             if(low[x]>dfn[y])low[x]=dfn[y];
 63         }
 64     }
 65     if(dfn[x]==low[x])
 66     {
 67         int v;
 68         zz5++;
 69         do{
 70             v=st[top];
 71             top--;
 72             rd[v]=0;
 73             size[zz5]++;
 74             bel[v]=zz5;
 75         }while(low[v]!=dfn[v]);
 76     }
 77 }
 78 int zz,a[M],rdd[M],fw[M];
 79 void build(int x,int y)
 80 {
 81     zz++;
 82     road[zz].to=y;
 83     road[zz].next=a[x];
 84     a[x]=zz;
 85 }
 86 int dfs(int x)
 87 {
 88     if(fw[x])return fw[x];
 89     int ans=0;
 90     for(int i=a[x];i>0;i=road[i].next)
 91     {
 92         int y=road[i].to;
 93         int t=dfs(y);
 94         if(t>ans)ans=t;
 95     }
 96     return fw[x]=ans+size[x];
 97 }
 98 int main()
 99 {
100     scanf("%d%d%d",&n,&r,&c);
101     for(int i=1;i<=n;i++)
102     {
103         int x,y,op;
104         scanf("%d%d%d",&x,&y,&op);
105         node[i].x=x,node[i].y=y,node[i].op=op;
106         build1(x,i);
107         build2(y,i);
108     }
109     for(int i=1;i<=n;i++)
110     {
111         int x=node[i].x,y=node[i].y;
112         if(node[i].op==1)
113         {
114             for(int j=a1[x];j>0;j=road1[j].next)
115             {
116                 int to=road1[j].to;
117                 if(to!=i)
118                 {
119                     build3(i,to);
120                 }
121             }
122         }
123         else if(node[i].op==2)
124         {
125             for(int j=a2[y];j>0;j=road2[j].next)
126             {
127                 int to=road2[j].to;
128                 if(to!=i)
129                 {
130                     build3(i,to);
131                 }
132             }
133         }
134         else
135         {
136             int t;
137             for(int j=a2[y-1];j>0;j=road2[j].next)
138             {
139                 int to=road2[j].to;
140                 t=node[to].x-node[i].x;
141                 if(t>=-1&&t<=1)build3(i,to);
142             }
143             for(int j=a2[y];j>0;j=road2[j].next)
144             {
145                 int to=road2[j].to;
146                 t=node[to].x-node[i].x;
147                 if(t>=-1&&t<=1&&to!=i)build3(i,to);
148             }
149             for(int j=a2[y+1];j>0;j=road2[j].next)
150             {
151                 int to=road2[j].to;
152                 t=node[to].x-node[i].x;
153                 if(t>=-1&&t<=1)build3(i,to);
154             }
155         }
156     }
157     //exit(0);
158     for(int i=1;i<=n;i++)
159     {
160         if(!rd2[i])
161             tarjan(i);
162     }
163     for(int i=1;i<=n;i++)
164     {
165         for(int j=b[i];j>0;j=road3[j].next)
166         {
167             int y=road3[j].to;
168             if(bel[i]!=bel[y])
169             {
170                 build(bel[i],bel[y]);
171                 rdd[bel[y]]++;
172             }
173         }
174     }
175     int ans=0;
176     for(int i=1;i<=zz5;i++)
177     {
178         if(!rdd[i])
179             ans=max(ans,dfs(i));
180     }
181     printf("%d\\n",ans);
182     return 0;
183 }
View Code

 

以上是关于10.12 考试 第三题 所驼门王的宝藏题解的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1924: [Sdoi2010]所驼门王的宝藏 题解

题解 [SDOI2010]所驼门王的宝藏

SDOI2010所驼门王的宝藏

[SDOI2010] 所驼门王的宝藏

BZOJ:1924: [Sdoi2010]所驼门王的宝藏

bzoj 1924: [Sdoi2010]所驼门王的宝藏