bzoj 1924 所驼门王的宝藏
题目大意:
有一个r*c的矩阵,上面有n个点有宝藏
每个有宝藏的点上都有传送门
传送门有三种:第一种可以传到该行任意一个有宝藏的点,第二种可以传到该列任意一个有宝藏的点,第三种可以传到周围的八连块上有宝藏的点
现在你可以在任意一个有宝藏的点开始,求你最多可以经过多少个不同的藏宝点
每个藏宝点可以多次进入,每个传送门可以多次使用
思路:
很容易可以看出这个矩阵并没有什么卵用
而此题的关键在于如何建图,建图所用数组见注释
建完之后,可以使用tarjan算法之一的求强连通分量
因为对于每个强连通分量,只要到达任意一个点,就可以到达其余所有点
然后我们缩点,把每个强连通分量都缩为一个点
再重新建图
这样图就会变成DAG,然后求一下最长链并统计每一个强连通分量内有几个点就好了
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<stack> 10 #include<set> 11 #include<map> 12 #define inf 2147483611 13 #define ll long long 14 #define MAXN 101001 15 using namespace std; 16 inline int read() 17 { 18 int x=0,f=1; 19 char ch;ch=getchar(); 20 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 21 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 22 return x*f; 23 } 24 int dx[8]={1,1,1,-1,-1,-1,0,0},dy[8]={1,0,-1,1,0,-1,1,-1};//八连块用数组 25 map <int,int> m[10*MAXN];//记录每个位置是否有藏宝点,因为数组开不下只能用map 26 vector <int> vr[10*MAXN],vc[10*MAXN];//记录每行每列所有藏宝点,用vector方便记录 27 int n,r,c; 28 int x[MAXN],y[MAXN];//记录每个点的横纵坐标 29 short t[MAXN];//记录每个点的传送门种类 30 int to[10*MAXN],next[10*MAXN],first[MAXN],cnt;//第一次图用邻接表 31 int to0[10*MAXN],next0[10*MAXN],first0[MAXN];//DAG第二次图用邻接表 32 int low[MAXN],dfn[MAXN],stp,scc,now,st[MAXN],top;//tarjan用数组 33 //scc记录一共有多少强连通分量,stp记录步数,st、top记录栈 34 int num[MAXN],blg[MAXN];//num记录每个强连通分量中有多少个点,blg记录每个点属于那个强连通分量 35 int deep[MAXN];//求最长链用,记录每个强连通分量能延伸的最长长度 36 int ans; 37 bool vis[MAXN];//第一次为tarjan用,第二次求最长链用 38 void add(int u,int v)//第一次建图 39 { 40 if(u==v) return ; 41 to[++cnt]=v,next[cnt]=first[u],first[u]=cnt; 42 } 43 void ADD(int u,int v) {to0[++cnt]=v,next0[cnt]=first0[u],first0[u]=cnt;}//第二次建图 44 void build()//第一次建图 45 { 46 int tmp,s; 47 for(int i=1;i<=r;i++)//同一行的藏宝图 48 { 49 tmp=0,s=vr[i].size(); 50 for(int j=0;j<s;j++) if(t[vr[i][j]]==1) {tmp=vr[i][j];break;} 51 for(int j=0;j<s;j++) 52 { 53 add(tmp,vr[i][j]); 54 if(t[vr[i][j]]==1) add(vr[i][j],tmp);//不用连所有边,只需要这样就可以满足要求 55 } 56 } 57 for(int i=1;i<=c;i++)//同一列,方法同上 58 { 59 tmp=0,s=vc[i].size(); 60 for(int j=0;j<s;j++) if(t[vc[i][j]]==2) {tmp=vc[i][j];break;} 61 for(int j=0;j<s;j++) 62 { 63 add(tmp,vc[i][j]); 64 if(t[vc[i][j]]==2) add(vc[i][j],tmp); 65 } 66 } 67 for(int i=1;i<=n;i++)//八连块 68 if(t[i]==3) 69 for(int j=0;j<8;j++) if(m[x[i]+dx[j]][y[i]+dy[j]]) add(i,m[x[i]+dx[j]][y[i]+dy[j]]); 70 } 71 void tarjan(int x)//tarjan求强连通分量 72 { 73 low[x]=dfn[x]=++stp; 74 st[++top]=x;vis[x]=1; 75 for(int i=first[x];i;i=next[i]) 76 if(!dfn[to[i]]) 77 {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}//在栈外且未被访问过 78 else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);//在栈内 79 if(low[x]==dfn[x]) 80 { 81 scc++;now=0; 82 while(now!=x) 83 { 84 now=st[top--];vis[now]=0; 85 blg[now]=scc;num[scc]++; 86 } 87 } 88 } 89 void BUILD()//第二次建图 90 { 91 for(int i=1;i<=n;i++) 92 for(int j=first[i];j;j=next[j]) 93 if(blg[i]!=blg[to[j]]) ADD(blg[i],blg[to[j]]); 94 } 95 void dp(int x)//求最长链 96 { 97 vis[x]=1; 98 for(int i=first0[x];i;i=next0[i]) 99 { 100 if(!vis[to0[i]]) dp(to0[i]); 101 deep[x]=max(deep[x],deep[to0[i]]);//延伸 102 } 103 deep[x]+=num[x]; 104 ans=max(ans,deep[x]); 105 } 106 int main() 107 { 108 n=read(),r=read(),c=read(); 109 for(int i=1;i<=n;i++) 110 { 111 x[i]=read(),y[i]=read(),t[i]=read(); 112 m[x[i]][y[i]]=i; 113 vr[x[i]].push_back(i); 114 vc[y[i]].push_back(i); 115 } 116 build(); 117 for(int i=1;i<=n;i++) 118 if(!dfn[i]) tarjan(i); 119 cnt=0; 120 BUILD(); 121 for(int i=1;i<=scc;i++) 122 if(!vis[i]) dp(i); 123 printf("%d",ans); 124 }
View Code
转载于:https://www.cnblogs.com/yyc-jack-0920/p/7617320.html
bzoj 1924 所驼门王的宝藏相关推荐
- BZOJ1924: [Sdoi2010]所驼门王的宝藏
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MB Submit: 1303 Solved: 582 [Submit][S ...
- P2403 [SDOI2010]所驼门王的宝藏
P2403 [SDOI2010]所驼门王的宝藏 题意: R * C的地图上有n个宝藏,给你n个宝藏的坐标,每个宝藏的位置上还有一个传送门,传送门有三种类型,1.可以传送到同行的其他宝藏位置,2.可以传 ...
- 8.18 NOIP模拟测试25(B) 字符串+乌鸦喝水+所驼门王的宝藏
T1 字符串 卡特兰数 设1为向(1,1)走,0为向(1,-1)走,限制就是不能超过$y=0$这条线,题意转化为从(0,0)出发,走到(n+m,n-m)且不越过$y=0$,然后就裸的卡特兰数,$ans ...
- 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- 洛谷P2403 [SDOI2010]所驼门王的宝藏
Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的 Alpaca L. Sotomon 是这个家族的领袖,外人也称其为"所驼 ...
- [SDOI2010] 所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- 洛谷 2403 [SDOI2010] 所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- bzoj 1924: [Sdoi2010]所驼门王的宝藏
23333这个垃圾题之前扒过题解了2333 然而这一次做又错了... 直接暴力连边,然后缩一下点,重构变成DAG,然后DP.. (然而在打tarjan的时候忘掉了inq[now]=0....而且把DP ...
- BZOJ 1924 [Sdoi2010]所驼门王的宝藏
Description Input Output Sample Input 题解: 水题,但还是打表过的-- 这个题目,我们显然可以对关键点进行加边.我就是因为加边加太多了才MLE的,当然对于1,2这 ...
- BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP
题意: 一个r*c的图中,有n个宫殿. 每个宫殿有一个类型. 类型1:可以到达他所在的行的任意宫殿. 类型2:可以到达他所在的列的任意宫殿. 类型3:可以到达他四周八个格子的任意宫殿. 现在你从任意一 ...
最新文章
- 知否?知否?一文看懂深度文本分类之DPCNN原理与代码
- cve-2018-1273 Spring Expression Language 漏洞分析
- Backup--修改实例级别是否使用压缩备份的默认值
- JS-原型-原型链-值和引用类型
- 文泉驿正黑 font JAVA,字体 | 免费可商用字体~文泉驿正黑体
- 运用spss modeler运用支持向量机_统计分析软件SPSS初阶应用
- 开源项目: FlycoTabLayout SlidingTabLayout不显示字体的问题
- 12306排队是什么意思_12306抢票显示排队中怎么办
- 读书笔记 | 财务会计理论(第7版 William R.Scott)(上)
- 计算机u盘被禁用怎么办,u盘禁用了怎么恢复,u盘一启用马上就被禁用
- 需要u3d资源吗,免费送哦
- DNA转换为C语言,DNA (C语言代码)
- 《穷查理宝典》听书笔记
- 节约粮食海报|节约粮食就是对袁隆平院士最好的怀念!
- HSA人血清白蛋白修饰纳米金球金棒
- 2021年河南省高考成绩位次查询,2021年河南高考位次查询及一分一段表排名查询...
- KVO实现机制 如何自己动手实现 KVO
- win 10 取消用户帐户控制
- python依赖包turbojpeg(PyTurboJPEG)安装
- 《唐伯虎点秋香》中的超级对联