BZOJ 1924

内存要算准,我MLE了两次。

建立$n + r + c$个点,对于一个点$i$的坐标为$(x, y)$,连边$(n + x, i)$和$(n + r + y, i)$,代表这一列和这一行可以走到它,如果类型为$1, 2$只要连一条到所在行和所在列的边就可以了,但是类型$3$似乎没有什么好的方法,$map$或者$hash$搞一搞,暴力连一连。

然后缩点之后记忆化搜索一下就可求出最长链了。

点数为$n + r + c$最多不超过$2e6 + 1e5$,边数为$2e5 + $最多$8e5$,不会达到这个上界。

时间复杂度$O(nlogn)$,$log$来源于$map$。

Code:

#include <cstdio>
#include <cstring>
#include <map>
#include <iostream>
#include <vector>
using namespace std;
typedef pair <int, int> pin; const int N = 2e6 + 1e5 + ;
const int M = 1e6 + ;
const int dx[] = {-, -, -, , , , , };
const int dy[] = {-, , , -, , -, , }; int n, r, c, tot = , head[N], scc = , bel[N], f[N];
int dfsc = , dfn[N], low[N], top = , stk[N], deg[N];
bool vis[N];
map <pin, int> mp;
vector <int> G[N]; struct Edge {
int to, nxt;
} e[M]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} struct Node {
int x, y, type;
} a[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} inline int min(int x, int y) {
return x > y ? y : x;
} void tarjan(int x) {
dfn[x] = low[x] = ++dfsc;
vis[x] = , stk[++top] = x;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if(vis[y])
low[x] = min(low[x], dfn[y]);
} if(low[x] == dfn[x]) {
++scc;
for(; stk[top + ] != x; --top) {
vis[stk[top]] = ;
bel[stk[top]] = scc;
if(stk[top] >= && stk[top] <= n) ++f[scc];
}
}
} void dfs(int x) {
if(vis[x]) return;
int res = , vecSiz = G[x].size();
for(int i = ; i < vecSiz; i++) {
int y = G[x][i];
dfs(y);
chkMax(res, f[y]);
}
f[x] += res;
vis[x] = ;
} int main() {
read(n), read(r), read(c);
for(int i = ; i <= n; i++) {
read(a[i].x), read(a[i].y), read(a[i].type);
mp[pin(a[i].x, a[i].y)] = i;
add(a[i].x + n, i), add(a[i].y + n + r, i);
}
for(int i = ; i <= n; i++) {
if(a[i].type == ) add(i, a[i].x + n);
if(a[i].type == ) add(i, a[i].y + n + r);
if(a[i].type == ) {
for(int j = ; j < ; j++) {
int tox = a[i].x + dx[j], toy = a[i].y + dy[j];
if(tox >= && tox <= r && toy >= && toy <= c) {
if(mp.find(pin(tox, toy)) != mp.end())
add(i, mp[pin(tox, toy)]);
}
}
}
} for(int i = ; i <= n + r + c; i++)
if(!dfn[i]) tarjan(i); for(int x = ; x <= n + r + c; x++) {
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(bel[x] == bel[y]) continue;
G[bel[x]].push_back(bel[y]);
++deg[bel[y]];
}
} for(int i = ; i <= scc; i++)
if(!deg[i]) dfs(i); int ans = ;
for(int i = ; i <= scc; i++)
chkMax(ans, f[i]); printf("%d\n", ans);
return ;
}

Luogu 2403 [SDOI2010]所驼门王的宝藏的更多相关文章

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

    题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐, ...

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

    比较显然的缩点+拓扑排序题,只不过要建虚点优化建边. 首先我们发现在一个SCC里的点都是可以一起对答案产生贡献的,因此先缩成DAG,然后拓扑找最长链. 但是我们发现这题最坏情况下边数会达到恐怖的\(O ...

  3. BZOJ 1924 && Luogu P2403 [SDOI2010]所驼门王的宝藏 恶心建图+缩点DP

    记住:map一定要这么用: if(mp[x[i]+dx[j]].find(y[i]+dy[j])!=mp[x[i]+dx[j]].end()) add(i,mp[x[i]+dx[j]][y[i]+dy ...

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

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1285  Solved: 574[Submit][Sta ...

  5. 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)

    [题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...

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

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

  7. [LuoguP2403][SDOI2010]所驼门王的宝藏

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

  8. BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】

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

  9. 【洛谷2403】[SDOI2010] 所驼门王的宝藏(Tarjan+dfs遍历)

    点此看题面 大致题意: 一个由\(R*C\)间矩形宫室组成的宫殿中的\(N\)间宫室里埋藏着宝藏.由一间宫室到达另一间宫室只能通过传送门,且只有埋有宝藏的宫室才有传送门.传送门分为3种,分别可以到达同 ...

随机推荐

  1. java多线程:线程体往外抛出异常的处理机制实践

    1当线程的线程体内部无捕获异常,将异常抛出线程体外,不同情况下,程序处理机制 测试类 package com.ehking.bankchannel.domesticremit.facade.impl; ...

  2. 洛谷P1979 华容道

    神の契约 题目大意:自己看去... 题解:做了一下午...本蒟蒻立志要写全网最详细的题解.╭(╯^╰)╮ begin.... 暴力70分.可以让空格子到处乱走,只要某个状态的指定格子到目标格子,那么此 ...

  3. JAMstack 技术要点

    1.  简要说明 Modern web development architecture based on client-side JavaScript, reusable APIs,and preb ...

  4. oracle之 oradebug 命令用法

    0> oradebug使用步骤 1)启动sql*plus并以sysdba身份登入 2)连接到一个进程 3)设置一个事件或者进行诊断转储 4)检索trc文件名 5)与连接到的进程断开 1> ...

  5. MongoDB-WriteConcern

    WriteConcern safe=false 非安全模式 很快

  6. 【转】JMeter中使用Selenium进行测试

    JMeter是使用非常广泛的性能测试工具,而Selenium是ThroughtWorks 公司一个强大的开源Web 功能测试工具.Jmeter和Selenium结合使用,就可以实现对网站页面的自动化性 ...

  7. 有趣的java小项目------猜拳游戏

    package com.aaa; //总结:猜拳游戏主要掌握3个方面:1.人出的动作是从键盘输入的(System.in)2.电脑是随机出的(Random随机数)3.双方都要出(条件判断) import ...

  8. java中length的用法

    总结:length是属性...有很多种,不仅仅是指长度 package com.c2; import java.io.BufferedReader; import java.io.IOExceptio ...

  9. [PYTHON 实作] 算100

    问题:编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性.例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 100 ...

  10. php.ini修改php上传文件大小限制

    打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...