题面传送门:

传送门

思路:

看完题建模,容易得出是求单向图最长路径的问题

那么把这张图缩强联通分量,再在DAG上面DP即可

然而

这道题的建图实际上才是真正的考点

如果对于每一个点都直接连边到它所有的后继节点,那么可以被卡掉(1e5个点在同一行上)

考虑改变思路,运用网络流建图中的一个常用技巧:把横边和竖边映射成点,再从每个点向所在横坐标、纵坐标代表的点连边即可

这样会有2e6+1e5个点,但是tarjan算法效率O(n),完全无压力

自由(和谐)门的话,目前还没有比较好的方法解决

上网看了一圈题解,也都是排序或者map的

这里就用map

//为什么自由(和谐)门会是违规的啊......

Code:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#define mp make_pair
#pragma comment(linker, "/STACK:202400000,202400000")
using namespace std;
const int dx[]={,,,,,,-,-,-},dy[]={,-,,,-,,-,,};
inline int read(){
int re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
int n,r,c,first[],First[],cnt=,Cnt=;
int dfn[],low[],num=;
int s[]={},top=;
int belong[],tot=,dp[],siz[],in[];
bool vis[];
int x[],y[];
struct edge{
int from,to,next;
}a[];
struct Edge{
int to,next;
}e[];
inline void add(int u,int v){
// cout<<"add "<<u<<ends<<v<<endl;
a[++cnt]=(edge){u,v,first[u]};first[u]=cnt;
}
inline void Add(int u,int v){
e[++Cnt]=(Edge){v,First[u]};First[u]=Cnt;
}
map<pair<int,int>,int>m;
void tarjan(int u){
// cout<<"tarjan "<<u<<endl;
int i,v;vis[u]=;
dfn[u]=low[u]=++num;
s[++top]=u;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;
if(belong[v]) continue;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++tot;
while(s[top]!=u){
belong[s[top]]=tot;
if(s[top]>r+c) siz[tot]++;
// qlt[tot].push_back(s[top]);
s[top--]=;
}
belong[s[top]]=tot;
if(s[top]>r+c) siz[tot]++;
// qlt[tot].push_back(s[top]);
s[top--]=;
}
}
int q[],head=,tail=;
int main(){
// freopen("sdoi10sotomon.in","r",stdin);
// freopen("sdoi10sotomon.out","w",stdout);
memset(first,-,sizeof(first));
memset(First,-,sizeof(First));
int i,t1,t2,t3,t4,t5,j,u,v,ans=;
map<pair<int,int>,int>::iterator tmp;
memset(first,-,sizeof(first));
n=read();r=read();c=read();
for(i=;i<=n;i++){
t1=read();t2=read();t3=read();
x[i]=t1;y[i]=t2;
m[mp(t1,t2)]=i;
add(t1,r+c+i);add(t2+r,i+r+c);
if(t3==) add(r+c+i,t1);
if(t3==) add(r+c+i,r+t2);
if(t3==) vis[i]=;
}
for(i=;i<=n;i++){
if(!vis[i]) continue;
t1=x[i];t2=y[i];
for(j=;j<=;j++){
t3=t1+dx[j];t4=t2+dy[j];
tmp=m.find(mp(t3,t4));
if(tmp==m.end()) continue;
add(r+c+i,r+c+tmp->second);
}
}
memset(vis,,sizeof(vis));
for(i=;i<=r+c+n;i++) if(!vis[i]) tarjan(i);
// cout<<"end of tarjan"<<endl;
// for(i=1;i<=r+c+n;i++) cout<<belong[i]<<ends;
// for(i=1;i<=tot;i++){
// for(j=0;j<qlt[i].size();j++) cout<<qlt[i][j]<<ends;
// cout<<endl;
// }
for(i=;i<=cnt;i++){
if(!belong[a[i].from]||!belong[a[i].to]) continue;
if(belong[a[i].from]==belong[a[i].to]) continue;
Add(belong[a[i].from],belong[a[i].to]);in[belong[a[i].to]]++;
}
// cout<<"end of Add\n";
for(i=;i<=tot;i++) if(!in[i]) q[tail++]=i,dp[i]=siz[i];
while(head<tail){
u=q[head++];
for(i=First[u];~i;i=e[i].next){
v=e[i].to;
dp[v]=max(dp[v],dp[u]+siz[v]);in[v]--;
if(!in[v]) q[tail++]=v;
}
}
for(i=;i<=tot;i++) ans=max(ans,dp[i]);
printf("%d",ans);
}

[SDOI2010] 所驼门王的宝藏 [建图+tarjan缩点+DAG dp]的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)

    Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...

  8. 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 ...

  9. BZOJ1924 [Sdoi2010]所驼门王的宝藏 【建图 + tarjan】

    题目 输入格式 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti.Ti ...

随机推荐

  1. 浅谈 import / export

    import { ngModule } from '@angular/core'; import { AppComponent } from './app.component'; export cla ...

  2. SpringBoot操作MongoDB实现增删改查

    本篇博客主讲如何使用SpringBoot操作MongoDB. SpringBoot操作MongoDB实现增删改查 (1)pom.xml引入依赖 <dependency> <group ...

  3. 剑指offer:按之字形顺序打印二叉树(Python)

    题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 解题思路 先给定一个二叉树的样式: 前段时间 ...

  4. javaweb基础(29)_EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  5. unsigned __int64 打印方法

    原文出处 long 和 int 范围是[-2^31,2^31),即-2147483648~2147483647. 而unsigned范围是[0,2^32),即0~4294967295.也就是说,常规的 ...

  6. Apache服务器的安装和配置

    启动 Apache,让别人可以使用你机器上安装的 Apache 提供的 Web 服务,访问你机器上的网站.这种情况下你的机器就是服务器,别人的机器就是客户端 appsevApache服务器的基本安装 ...

  7. 洛谷P2468 [SDOI2010]粟粟的书架(二分答案 前缀和 主席树)

    题意 题目链接 给出一个矩形,每个点都有一些值,每次询问一个子矩阵最少需要拿几个数才能构成给出的值 Sol 这题是真坑啊.. 首先出题人强行把两个题拼到了一起, 对于前$50 \%$的数据,考虑二分答 ...

  8. 【原创】数据处理中判断空值的方法(np.isnan、is np.nan和pd.isna)比较

      转载请注明出处:https://www.cnblogs.com/oceanicstar/p/10869725.html  1.np.isnan(只有数组数值运算时可使用) 注意:numpy模块的i ...

  9. SQL初次接触

    1.SQL对大小写不敏感 2.部分SQL数据库要求结尾分号 3.分为两种DML(数据操作语言)和DDL(数据定义语言) sql中一些注意要点 1.设置主键 一般会在一个数据内设置一个主键(名字通常为i ...

  10. keepalived原理(主从配置+haproxy)及配置文件详解

    下图描述了使用keepalived+Haproxy主从配置来达到能够针对前段流量进行负载均衡到多台后端web1.web2.web3.img1.img2.但是由于haproxy会存在单点故障问题,因此使 ...