[SDOI2010] 所驼门王的宝藏 [建图+tarjan缩点+DAG dp]
题面传送门:
思路:
看完题建模,容易得出是求单向图最长路径的问题
那么把这张图缩强联通分量,再在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]的更多相关文章
- 【题解】SDOI2010所驼门王的宝藏(强连通分量+优化建图)
[题解]SDOI2010所驼门王的宝藏(强连通分量+优化建图) 最开始我想写线段树优化建图的说,数据结构学傻了233 虽然矩阵很大,但是没什么用,真正有用的是那些关键点 考虑关键点的类型: 横走型 竖 ...
- [BZOJ 1924][Sdoi2010]所驼门王的宝藏
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1285 Solved: 574[Submit][Sta ...
- [SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- [LuoguP2403][SDOI2010]所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为"先知"的Alpaca L. Sotomon是这个家族的领袖,外人也称其为"所驼门王". ...
- 洛谷 2403 [SDOI2010] 所驼门王的宝藏
题目描述 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”.所驼门王毕生致力于维护家族的安定与和谐, ...
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
Description 在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族.被族人恭称为“先 知”的Alpaca L. Sotomon 是这个家族的领袖,外人也称其为“所驼门王”.所 驼门王毕生致力于维 ...
- BZOJ1924:[SDOI2010]所驼门王的宝藏(强连通分量,拓扑排序)
Description Input 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室 ...
- 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 ...
- BZOJ1924 [Sdoi2010]所驼门王的宝藏 【建图 + tarjan】
题目 输入格式 第一行给出三个正整数 N, R, C. 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti.Ti ...
随机推荐
- Shuffle Cards
C: Shuffle Cards 时间限制: 1 Sec 内存限制: 128 MB提交: 3 解决: 3[提交] [状态] [讨论版] [命题人:admin] 题目描述 Eddy likes to ...
- 1.redis 安装
1.https://redis.io/download. 2. $ wget http://download.redis.io/releases/redis-3.2.9.tar.gz $ .tar.g ...
- c++中的结构化语句 判断语句if 分支语句switch 循环语句 while 和 do while 循环语句for的使用
作业1: 使用if语句,根据1~7的数字,输出今天是星期几?的程序. 方法一,直接使用单独的if语句 #include <iostream> using namespace std; in ...
- 洛谷P3371单源最短路径Dijkstra版(链式前向星处理)
首先讲解一下链式前向星是什么.简单的来说就是用一个数组(用结构体来表示多个量)来存一张图,每一条边的出结点的编号都指向这条边同一出结点的另一个编号(怎么这么的绕) 如下面的程序就是存链式前向星.(不用 ...
- python面向对象之反射和内置方法
一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被 ...
- Django框架基础知识01-配置环境
Django框架 Django是个怎样的东西呢? Web应用框架----Django http服务器:用来接受用户请求,并将请求转发给web应用框架进行处理. Web应用框架处理完以后再发送给htt ...
- Python3爬取起点中文网阅读量信息,解决文字反爬~~~附源代码
起点中文网,在“数字”上设置了文字反爬,使用了自定义的文字文件ttf通过浏览器的“检查”显示的是“□”,但是可以在网页源代码中找到映射后的数字正则爬的是网页源代码,xpath是默认utf-8解析网页数 ...
- 【luminate primordial】苏州之行
测试了reader 07版 更主要的是第一次坐了高铁 还不错 路上看到下雨的时候都是水顺着玻璃平着流 好厉害的样子 6个人去的6个人回 今儿开会 老板不太满意 小随意 对我来说,收获感觉还是不小的,使 ...
- 51nod 1105 二分答案法标准题目
二分答案法例题,用于练习二分答案的基本思想非常合适,包括了思维方式转换的内容(以前我们所做的一直是利用二分法求得数组元素对应指针之类,但是现在是直接对答案进行枚举). 思路是:首先对输入数组进行排序, ...
- Android 适配器 自定义
前言:最近看了几个开源项目,发现适配器这东西用的很多,一开始觉得这东西高大上,其实呢,感觉就是一个中转站,或者说是一个接口工具,将数据填充到一个视图中,几乎任何项目都会涉及到.所以今天也简单看了一下, ...