题意:
一个r*c的图中,有n个宫殿。
每个宫殿有一个类型。
类型1:可以到达他所在的行的任意宫殿。
类型2:可以到达他所在的列的任意宫殿。
类型3:可以到达他四周八个格子的任意宫殿。
现在你从任意一个宫殿开始,询问你最多访问多少个宫殿。
解析:
填坑计划。
这题建边好麻烦=-=
首先先建出来从哪个宫殿可以到哪个宫殿的图。
之后我们发现对于一个强连通分量来说,如果访问了一个点,那么即可以访问该强连通分量中的所有点。
所以我们可以tarjan缩一下点,然后重新建图。
然后我们发现重新建出来的图是个DAG。
(不知道当年哪个2b说是一棵树?)
所以我们可以在这个DAG上拓扑DP,f[i]表示从某点出发到i最多走多少点权和(点的点权为强连通分量中的原来的点的个数)。
代码:

#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100001
using namespace std;
typedef long long ll;
ll n,r,c;
int xx[]={0,1,0,-1,-1,-1,0,1,1};
int yy[]={0,1,1,1,0,-1,-1,-1,0};
int head[N],head2[N],head3[N],head4[N];
int cnt,cnt2,cnt3,cnt4;
struct node
{int to,next;
}linkx[N*10],linky[N*10],newedge[N*10];
struct node2
{int from,to,next;
}edge[N*40];
struct Point
{int x,y,type;Point(){}Point(int _x,int _y):x(_x),y(_y){}friend istream& operator >> (istream &_, Point &a){scanf("%d%d%d",&a.x,&a.y,&a.type);return _;}friend bool operator < (Point a,Point b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;}
}pt[N];
map<ll,int>ma;
map<Point,int>ma2;
void init()
{memset(head2,-1,sizeof(head2));memset(head,-1,sizeof(head));cnt=1,cnt2=1;
}
void init2()
{memset(head3,-1,sizeof(head3));cnt3=1;
}
void init3()
{memset(head4,-1,sizeof(head4));cnt4=1;
}
void edgeadd(int from,int to,int *head,node *edge,int &cnt)
{edge[cnt].to=to,edge[cnt].next=head[from];head[from]=cnt++;
}
void edgeadd2(int from,int to,int *head,node2 *edge,int &cnt)
{edge[cnt].from=from,edge[cnt].to=to,edge[cnt].next=head[from];head[from]=cnt++;
}
bool ins[N];
int deep[N],low[N],sta[N],top,tot;
int belong[N],num[N],cnt_block;
void tarjan(int now,int ff)
{deep[now]=low[now]=++tot;sta[++top]=now,ins[now]=1;for(int i=head3[now];i!=-1;i=edge[i].next){int to=edge[i].to;if(!deep[to]){tarjan(to,now);low[now]=min(low[now],low[to]);}else if(ins[to])low[now]=min(low[now],deep[to]);}if(deep[now]==low[now]){cnt_block++;int t=-1;do{t=sta[top--];ins[t]=0;belong[t]=cnt_block;num[cnt_block]++;}while(t!=now);}
}
int in[N];
int f[N];
void topsort()
{queue<int>q;memset(f,-0x3f,sizeof(f));for(int i=1;i<=cnt_block;i++)if(!in[i])q.push(i),f[i]=num[i];while(!q.empty()){int u=q.front();q.pop();for(int i=head4[u];i!=-1;i=newedge[i].next){int to=newedge[i].to;f[to]=max(f[to],f[u]+num[to]);in[to]--;if(in[to]==0)q.push(to);}}
}
int main()
{#ifndef ONLINE_JUDGEfreopen("sotomon8.in","r",stdin);freopen("test.out","w",stdout);#endifinit(),init2();scanf("%lld%lld%lld",&n,&r,&c);for(int i=1;i<=n;i++){cin>>pt[i],ma[(ll)(pt[i].x-1)*c+pt[i].y]=i;edgeadd(pt[i].x,i,head,linkx,cnt);edgeadd(pt[i].y,i,head2,linky,cnt2);}for(int i=1;i<=n;i++){if(pt[i].type==1){for(int j=head[pt[i].x];j!=-1;j=linkx[j].next){   int to=linkx[j].to;if(to==i)continue;edgeadd2(i,to,head3,edge,cnt3);}}else if(pt[i].type==2){for(int j=head2[pt[i].y];j!=-1;j=linky[j].next){int to=linky[j].to;if(to==i)continue;edgeadd2(i,to,head3,edge,cnt3);}}else{for(int j=1;j<=8;j++){ll tmpx=pt[i].x+xx[j],tmpy=pt[i].y+yy[j];int no=ma[(ll)(tmpx-1)*c+tmpy];if(no!=0)edgeadd2(i,no,head3,edge,cnt3);}}}for(int i=1;i<=n;i++)if(!deep[i])tarjan(i,0);init3();for(int i=1;i<cnt3;i++){int x=edge[i].from,y=edge[i].to;if(belong[x]!=belong[y]&&!ma2[Point(belong[x],belong[y])])ma2[Point(belong[x],belong[y])]=1,edgeadd(belong[x],belong[y],head4,newedge,cnt4),in[belong[y]]++;}topsort();int ans=0;for(int i=1;i<=cnt_block;i++)ans=max(ans,f[i]);printf("%d\n",ans);#ifndef ONLINE_JUDGEfclose(stdin);fclose(stdout);#endifreturn 0;
}

BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP相关推荐

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

    23333这个垃圾题之前扒过题解了2333 然而这一次做又错了... 直接暴力连边,然后缩一下点,重构变成DAG,然后DP.. (然而在打tarjan的时候忘掉了inq[now]=0....而且把DP ...

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

    Description Input Output Sample Input 题解: 水题,但还是打表过的-- 这个题目,我们显然可以对关键点进行加边.我就是因为加边加太多了才MLE的,当然对于1,2这 ...

  3. BZOJ1924: [Sdoi2010]所驼门王的宝藏

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 1303  Solved: 582 [Submit][S ...

  4. P2403 [SDOI2010]所驼门王的宝藏

    P2403 [SDOI2010]所驼门王的宝藏 题意: R * C的地图上有n个宝藏,给你n个宝藏的坐标,每个宝藏的位置上还有一个传送门,传送门有三种类型,1.可以传送到同行的其他宝藏位置,2.可以传 ...

  5. 洛谷P2403 [SDOI2010]所驼门王的宝藏

    Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的 Alpaca L. Sotomon 是这个家族的领袖,外人也称其为"所驼 ...

  6. [SDOI2010] 所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  7. 洛谷 2403 [SDOI2010] 所驼门王的宝藏

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...

  8. P2403 [SDOI2010]所驼门王的宝藏(强连通分量)(拓扑排序)

    文章目录 题目描述 解析 代码 洛谷传送门 题目描述 解析 看题目要求很容易想到强连通分量缩点加拓扑dp 但是问题在于存图 第一感就是和暴力和每个点连边 但那样无论点数和边数都很爆炸 随后我们发现这个 ...

  9. 洛咕 P2403 [SDOI2010]所驼门王的宝藏

    简单tarjan. 一行的横天门如果暴力连边会被卡成平方,所以只要相邻两个横天门连双向边,再随便选一个横天门向整行连边即可.纵寰门同理.ziyou门直接map暴力连边. 然后tarjan直接dp. / ...

最新文章

  1. 刚火了的中台转头就拆,一大波公司放不下又拿不起来!
  2. Retrofit2 multpart多文件上传详解
  3. python注释以符号什么开始_python注释以什么符号开始
  4. 15年考的全国计算机应用技术,(2015年全国专业技术人员计算机应用能力考试.doc...
  5. 阿里中间件再获高度肯定,“三位一体”推动技术普惠
  6. java解析dxf文件_CAD文件无法打开,这两点原因你必须要知道
  7. 跨域总结(jquery,php)
  8. C++ 11 新特性
  9. ks线切割编程系统3.13完整版-2次加密注册码
  10. python生成可执行exe控制Microsip自动填写号码并拨打
  11. eps在c语言,C语言中eps指的是什么东西?
  12. 【蓝桥杯冲刺 day12】题目全解析
  13. 面试题:spring的循环依赖问题以及如何解决
  14. 北邮iptv用WindowsMediaplayer打不开的解决的方法
  15. 全球人工智能产业链产业图谱
  16. 51单片机智能温控风扇
  17. 神经网络反向传播算法原理笔记
  18. linux 查看硬盘空间
  19. VB.net学习笔记(二十九)认识STA与MTA
  20. 行进中换轮胎——万字长文解析美团和大众点评两大数据平台是怎么融合的

热门文章

  1. 人工智能:从图灵到未来
  2. 陈艾盐:春燕百集访谈节目第二十三集
  3. mac m1 homebrew安装
  4. pcf8563c语言程序,PCF8563T标准驱动源程序
  5. 根椐图片,请猜一四字成语!有一点难度喔:)
  6. 二叉树、平衡二叉树、红黑树、B-树、B+树、B*树、T树之间的详解和比较
  7. ubuntu22 使用todesk被远程控制时显示黑屏或者白屏
  8. 使用Matlab实现脉冲响应不变法
  9. 苹果手机投影_智能投影机和手机无线同屏
  10. 使用calibre制作带目录的mobi电子书