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