[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 ...
随机推荐
- 【转】CentOS 7.0 安装Redis 3.2.1详细过程和使用常见问题
http://www.linuxidc.com/Linux/2016-09/135071.htm 环境:CentOS 7.0 Redis 3.2.1 Redis的安装与启动 这里我把Redis放在/h ...
- 基础I/O
基础IO: c库文件IO操作接口:(详细查看c语言中的文件操作函数总结:https://www.cnblogs.com/cuckoo-/p/10560640.html) fopen 打开文件 fclo ...
- Linux下Jenkins与GitHub自动构建NetCore与部署
今天我们来谈谈NetCore在Linux底下的持续集成与部署.NetCore我就不多介绍了,持续集成用的是Jenkins,源代码管理器用的是GitHub.我们就跟着博文往下走吧. 1.Linux环境 ...
- 防止sql注入方法 如何防止java中将MySQL的数据库验证密码加上 ' or '1'= '1 就可以出现万能密码 的PreparedStatement
package com.swift; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepar ...
- Centos 安装python 3.7 ,同时兼容python2.7
下载Python源码 从http://www.python.org/download/根据需要的版本下载源文件. 例如上图就是我在官网直接找到3.5.6版本的下载页面,点击的tar源码包进行下载. 1 ...
- linux运维、架构之路-MySQL多实例
一.MySQL多实例介绍 一台服务器上开启多个不同的服务端口(3306,3307,3308),运行多个MySQL服务进程,共用一套MySQL安装程序,多实例MySQL在逻辑上看是 ...
- GPIO实现I2C协议模拟(1)
最近需要用GPIO模拟I2C协议,如果是在Linux下面比较简单,但在Windows下面,是否有没Linux那么简单了. 索性自己对I2C协议还有一些了解,翻了SPEC并结合示波器量出的实际信号分析, ...
- 基于python3.7的一个闯越自动签到脚本--demo版
望指正demo的定位,有时候会抽风无法接受我的定位信息 #! /usr/bin/python3 # -*- coding:UTF- -*- # time : // : # file : chuangy ...
- python3 包的发布
发布流程大概如下 1. 首先需要有一个python包,就是一个文件夹,但是此文件夹下面有__init__.py文件,里面内容是 现在要发布包TestMsg,这就是一个python包.在同级目录下新建s ...
- 关于欧几里德算法(gcd)的证明
求a,b的最大公约数我们经常用欧几里得算法解决,也称辗转相除法, 代码很简短, int gcd(int a,int b){ return (b==0)?a:gcd(b,a%b); } 但其中的道理却很 ...