题面传送门:

传送门

思路:

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

那么把这张图缩强联通分量,再在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. 交叉验证(Cross Validation)方法思想简介

      以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train ...

  2. ERR_FAILED 浏览器访问

    我是针对上一篇的问题 继续的探究  ,我百度了 看了这 https://zhidao.baidu.com/question/1175643597811783659.html 之后我就用 电脑管家进行系 ...

  3. js基础之语言部分必须要掌握的五大方阵

    javascript基础部分可以从"数组, 函数, 作用域, 对象, 标准库"这5大方阵进行学习: (一).数组 数组的声明(2种):; a,自变量声明 var a = ['a', ...

  4. advanced regression to predict housing prices

    https://docs.google.com/presentation/d/e/2PACX-1vQGlXP6QZH0ATzXYwnrXinJcCn00fxCOoEczPAXU-n3hAPLUfMfi ...

  5. 1043: [HAOI2008]下落的圆盘

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1725  Solved: 743[Submit][Status][Discuss] Descripti ...

  6. WireShark抓包命令

    本机环回包 在进行通信开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以. 具体方法如 ...

  7. nginx安装php环境

    1.php下载地址 https://secure.php.net/downloads.php(此次安装版本为7.0.33) 2.安装依赖的包 yum -y install libxml2 yum -y ...

  8. 常用自写函数[更新ing]

    int gcd (int x, int y)//最大公约数 { return y == 0 ? x : gcd( y , x % y ); } int lcm(int x, int y)//最小公倍数 ...

  9. vscode运行C/C++程序及配置

    安装vscdoe,安装tdm-gcc-64编译器,这样可以自动把mingw的目录添加到环境变量中,其实安装其他编译器本版都可以,只要手动添加环境变量即可.平台win10-64位.此文参考了哔哩哔哩的配 ...

  10. makefile学习(1)

    GNU Make / Makefile 学习资料 GNU Make学习总结(一) GNU Make学习总结(二) 这篇学习总结,从一个简单的小例子开始,逐步加深,来讲解Makefile的用法. 最后用 ...