[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 ...
随机推荐
- 复习C++_指针、动态分配内存
注意:++i指的是先计算i+1,然后将其赋给i cout<<str[7]<<endl; //输出a 注:交换失败 注意:delete释放之后,变为迷途指针. 注:n--> ...
- android studio 安装以及遇到的一些问题
1 安装 jkd ,版本一般是最新的,下怎么样的看一下自己电脑符合那种要求,可以去官网下 https://www.oracle.com/technetwork/java/javase/download ...
- install ipython-notebook
http://it.010lm.com/os/LINUX/182036.html ipython[notebook]安装(Linux平台) 1. 环境 操作系统:ubuntukylin 2. 操作步骤 ...
- Linux下 tomcat 的开机自启动设置
每次开机都要启动tomcat,非常麻烦:通过直接修改系统文件,实现tomcat自启动: 1. 修改脚本文件rc.local:vim /etc/rc.d/rc.local 这个脚本是使用者自定的开机启动 ...
- linux几种文件传输方式
本文记录linux系统中文件传输的多种方式,留作备忘.linux中文件传输的方式有ftp,scp,rsync,rz,sz等,但各个工具的功能又有所区别: FTP : FTP是文件服务器,可实现文件的上 ...
- win10下安装mysql-5.7.23-winx64
Step1 官方下载地址 https://dev.mysql.com/downloads/mysql/ 选择手动下载版本 解压到自己指定的路径 上图中的my.ini及data文件夹在压缩包里是没有的, ...
- selinux详解及配置文件
selinux详解 selinux 的全称是Security Enhance Linux,就是安全加强的Linux.在Selinux之前root账号能够任意的访问所有文档和服务 : 如果某个文件设为7 ...
- Node.js 中流操作实践
本文节选自 Node.js CheatSheet | Node.js 语法基础.框架使用与实践技巧,也可以阅读 JavaScript CheatSheet 或者 现代 Web 开发基础与工程实践 了解 ...
- 【CSS】CSS 的优先级总结
样式的优先级 多重样式(Multiple Styles):如果外部样式.内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况. 一般情况下,优先级如下: (外部样式)External styl ...
- Bank Simulation Program银行管理系统C++ :)
设计并实现简单的银行存取款系统,系统主界面包括登录和注册两个选项,选择登录,提示用户输入银行帐号和密码,验证通过后进入主界面,主界面包括:存款.取款.查询余额.历史记录.修改密码等功能.注册功能让用户 ...