P2403 [SDOI2010]所驼门王的宝藏

题意:

R * C的地图上有n个宝藏,给你n个宝藏的坐标,每个宝藏的位置上还有一个传送门,传送门有三种类型,1.可以传送到同行的其他宝藏位置,2.可以传送到同列的其他宝藏位置 3.可以传送到该点周围的八个位置
你可以在任意一个宝藏处开始,问最多获得多少宝藏?

题解:

如果我们直接按照题意要求建边,(暴力建边,第1类门和每行其他门建边,第2,3类门同理),会得到一个有向有环图,对于环我们可以用tarjan进行缩点,然后得到DAG,然后就是在DAG直接dp求就行(拓扑排序)。
dp[v]=max(dp[u]+val[v])dp[v]=max(dp[u]+val[v] )dp[v]=max(dp[u]+val[v])
但是数据告诉我们不会这么简单,N<=100000,R<=1000000,C<=1000000
边的数量巨大,可达O(n2n^2n2),所以需要一个巧妙的建边方法来降低复杂度
原始的建边是两两之间建立练习,避免不了是O(n2n^2n2),现在我们可以这样想,对于每行,每列都建立一个额外的点,然后让所有点与这个额外的点建立联系。
第i行的额外的点为x,我们让x向改行所有宝藏建一个边,如果有一个点y是1号门,我们就让y再向x建一个边,通过这样操作,y就是本行任意一个宝藏位置(很妙,这个思路很妙)
列的同理
对于第三种门,我们就暴力枚举八个位置,然后在所有宝藏中二分寻找(事先要对宝藏位置排序),看是否能找到,找到即建边
思路捋清楚,就开干码吧

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){ll s=0,w=1ll;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
clock_t startTime, endTime;
void rd_test(){#ifdef ONLINE_JUDGE#elsestartTime = clock(); //计时开始freopen("sotomon.in","r",stdin);#endif
}
void Time_test(){#ifdef ONLINE_JUDGE#elseendTime = clock(); //计时结束printf("\n运行时间为:%lfs\n",(double)(endTime - startTime) / CLOCKS_PER_SEC);#endif
}
const int N = 2e5+9, T = 2100007, M = 1000007;
const int dx[8] = {1, 1, 1, 0, 0, -1, -1, -1};
const int dy[8] = {1, 0, -1, 1, -1, 1, 0, -1};
int n, r, c, t, edc, edu[M], edv[M];
int ecnt, head[T], nxt[M], vet[M];
int qhead, qtail, que[T], f[T], in[T];
int stac[T], top, val[T], col[T], stamp, dfn[T], low[T], cnt;
bool instac[T];
struct Node {int x, y, t;bool operator <(const Node &ano) const { return x < ano.x || x == ano.x && y < ano.y;}
} a[N]; inline void add(int u, int v) {edu[++edc] = u; edv[edc] = v;vet[++ecnt] = v; nxt[ecnt] = head[u];head[u] = ecnt;
}inline void eadd(int u, int v) {vet[++ecnt] = v; nxt[ecnt] = head[u];head[u] = ecnt;
}void tarjan(int u) {dfn[u] = low[u] = ++stamp;stac[++top] = u; instac[u] = true;for (int e = head[u]; e; e = nxt[e]) {int v = vet[e];if (!dfn[v]) {tarjan(v); low[u] = min(low[u], low[v]);} else if (instac[v]) low[u] = min(low[u], dfn[v]);}if (dfn[u] == low[u]) {col[u] = ++cnt; val[cnt] = u > r + c;while (stac[top] != u) {col[stac[top]] = cnt;val[cnt] += (stac[top] > r + c);instac[stac[top--]] = false;}instac[stac[top--]] = false;}
}int getid(int x, int y) {int l = 1, r = n;while (l <= r) {int mid = (l + r) >> 1;if (a[mid].x == x && a[mid].y == y) return mid;else if (a[mid].x < x || a[mid].x == x && a[mid].y < y) l = mid + 1;else r = mid - 1;}return -1;
}int main() {rd_test();scanf("%d%d%d", &n, &r, &c);for (int i = 1; i <= n; ++i) scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].t);sort(a + 1, a + 1 + n);for (int i = 1; i <= n; ++i) {//处理额外点对当前点的连边add(a[i].x, r + c + i); add(r + a[i].y, r + c + i);//处理当前点对其它点的连边if (a[i].t == 1) add(r + c + i, a[i].x);else if (a[i].t == 2) add(r + c + i, r + a[i].y);else {for (int k = 0; k < 8; ++k) {int x = a[i].x + dx[k], y = a[i].y + dy[k];if (x >= 1 && x <= r && y >= 1 && y <= c) {int id = getid(x, y);if (id != -1) add(r + c + i, r + c + id);} }}}//缩点 t = r + c + n; for (int i = 1; i <= t; ++i)if (!dfn[i]) tarjan(i);ecnt = 0; memset(head, 0, sizeof(head));for(int i = 1; i <= edc; ++i)if (col[edu[i]] != col[edv[i]]) {eadd(col[edu[i]], col[edv[i]]);++in[col[edv[i]]];}//拓扑排序qhead = 0; qtail = -1;for (int i = 1; i <= cnt; ++i) if (!in[i]) {que[++qtail] = i;f[i] = val[i];}while (qhead <= qtail) {int u = que[qhead++];for (int e = head[u]; e; e = nxt[e]) {int v = vet[e];f[v] = max(f[v], f[u] + val[v]);if (--in[v] == 0) que[++qtail] = v;}}//统计答案int ans = 0;for (int i = 1; i <= cnt; ++i)ans = max(ans, f[i]);printf("%d\n", ans);Time_test();return 0;
}

P2403 [SDOI2010]所驼门王的宝藏相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP

    题意: 一个r*c的图中,有n个宫殿. 每个宫殿有一个类型. 类型1:可以到达他所在的行的任意宫殿. 类型2:可以到达他所在的列的任意宫殿. 类型3:可以到达他四周八个格子的任意宫殿. 现在你从任意一 ...

最新文章

  1. 农村初中学校计算机课的意义,关于农村学校计算机课件使用的反思.pdf
  2. 如何用耳机翻页_游戏耳机的经典之作—罗技(G)Astro A40体验
  3. 番茄花园win11 32位官方纯净版镜像v2021.07
  4. 微信小程序自定义组件
  5. Sentinel熔断限流器工作原理
  6. ArcSDE数据库连接(直连、服务连)与GT_Geometry存储配置图解
  7. 为什么只有软件就可以用盗版?
  8. 【poj1995】Raising Modulo Numbers
  9. CAD中级的考证费用是多少?
  10. FlashFXP v3.5.4注册码+FlashFXP v3.6.0注册码+FlashFXP v3.7.2.build.1266...
  11. SAP ERP 与 Oracle ERP 比较(转)
  12. android 10.0禁用电源键(屏蔽关机短按长按事件)
  13. 泰凌微8258入门教程 基础篇⑤——发送数据流程
  14. css flash布局_跳过简介-CSS3是新的Flash
  15. python粒子风暴_气象雷达应用中常见的名词解释
  16. c语言专业自我评价,设计类专业简历自我评价
  17. 华为p10和p10plus区别_华为P10和华为P10Plus怎么样?哪个更值得买?华为P10与P10Plus区别对比...
  18. JAVA我的世界给op_我的世界手机版op指令大全 op指令怎么用
  19. python决策树案例_决策树案例:基于python的商品购买能力预测系统
  20. MOSFET 和 IGBT 栅极驱动器电路的基本原理学习笔记(六)变压器耦合栅极驱动

热门文章

  1. 要男女朋友有什么用?
  2. 奇妙的数学动图,美到令人窒息!
  3. 连锁反应装置积木好玩到尖叫!
  4. 不只是舒适,简直是享受,Google公司用的腰靠,到底有什么秘密?
  5. 辍学程序员改变世界,这位长得像马云的90后要击败Facebook的扎克伯格了…
  6. 我用Python玩小游戏“跳一跳”,瞬间称霸了朋友圈!
  7. nginx php oracle,第8天 ORACLE安装及NGINX整合PHP环境
  8. mysql 免费前端_MySQL
  9. python extended,python list中的append 与 extended 的区别
  10. 纳尼???我JVM优化过头了,直接把异常信息优化没了?怎么办