BZOJ1924——Tarjan+记搜
2018-03-01 15:22
260 查看
Description
Input
第一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“自由门”。 保证 1≤xi≤R,1≤yi≤C,所有的传送门位置互不相同。
Output
只有一个正整数,表示你确定的路线所经过不同藏宝宫室的最大数目。
Sample Input
10 7 7
2 2 1
2 4 2
1 7 2
2 7 3
4 2 2
4 4 1
6 7 3
7 7 1
7 5 2
5 2 1
Sample Output
9
Input
第一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“自由门”。 保证 1≤xi≤R,1≤yi≤C,所有的传送门位置互不相同。
Output
只有一个正整数,表示你确定的路线所经过不同藏宝宫室的最大数目。
Sample Input
10 7 7
2 2 1
2 4 2
1 7 2
2 7 3
4 2 2
4 4 1
6 7 3
7 7 1
7 5 2
5 2 1
Sample Output
9
这道题建图就挺烦的,因为有十万个点,直接N²建图会超时,我们采取vector的方式(用map也可以),用vector记录每个横纵坐标,就可以建图了。
建完图后,我们发现其实要求的是一张有向图的最长链,我们知道对于DAG我们可以用记忆化搜索,DP来做。然而这倒题目的图可能会出现环的情况,所以我们先用Tarjan,将环缩成点(这样整张图就变为DAG),然后再做一遍记忆化搜索即可。
Tarjan不会的点这里Vector版
#include<bits/stdc++.h> #include<vector> using namespace std; int read(){ char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x; } struct node{ int x,y,c; }f[100005]; vector<int> fx[1000005],fy[1000005],nxt[100005]; int sqr(int x){return x*x;} int n,r,c,low[100005],dfn[100005],col[100005],ta,co,top,dis[1000005],ans; int vis[100005],sta[100005]; struct edge{ int sum,in; vector<int> go; }p[100005]; void tarjan(int x){ vis[x]=1;low[x]=dfn[x]=++ta;sta[++top]=x; for(int i=0;i<nxt[x].size();i++){ int to=nxt[x][i]; if(!dfn[to]) tarjan(to),low[x]=min(low[x],low[to]); else if(vis[to]) low[x]=min(low[x],dfn[to]); } if(low[x]==dfn[x]){ co++; int now=0; while(now!=x){ now=sta[top]; top--; vis[now]=0; col[now]=co; p[co].sum++; } } } void dfs(int x){ for(int i=0;i<p[x].go.size();i++){ int to=p[x].go[i]; if(dis[x]+p[to].sum>dis[to]){ dis[to]=dis[x]+p[to].sum; dfs(to); } } } int main() { n=read();r=read();c=read(); for(int i=1;i<=n;i++){ f[i]=(node){read(),read(),read()}; fx[f[i].x].push_back(i); fy[f[i].y].push_back(i); } for(int i=1;i<=n;i++){ if(f[i].c==1){ for(int j=0;j<fx[f[i].x].size();j++){ int to=fx[f[i].x][j]; if(to!=i) nxt[i].push_back(to); } } if(f[i].c==2){ for(int j=0;j<fy[f[i].y].size();j++){ int to=fy[f[i].y][j]; if(to!=i) nxt[i].push_back(to); } } if(f[i].c==3){ for(int j=f[i].x-1;j<=f[i].x+1;j++) for(int k=0;k<fx[j].size();k++){ int to=fx[j][k]; if(to!=i&&sqr(f[i].x-f[to].x)+sqr(f[i].y-f[to].y)<=2) nxt[i].push_back(to); } } } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) for(int j=0;j<nxt[i].size();j++){ int to=nxt[i][j]; if(col[i]!=col[to]){ p[col[to]].in=1; p[col[i]].go.push_back(col[to]); } } for(int i=1;i<=co;i++){ if(p[i].in) continue; dis[i]=p[i].sum; dfs(i); } for(int i=1;i<=co;i++) ans=max(ans,dis[i]); printf("%d",ans); return 0; }
链表版
链表版代码相关文章推荐
- 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
- BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP
- bzoj1924 [Sdoi2010]所驼门王的宝藏(tarjan缩点+拓扑排序+dp)
- bzoj 1924: [Sdoi2010]所驼门王的宝藏 (tarjan缩点+spfa)
- BZOJ1924 tarjan+拓扑序
- [BZOJ1924][SDOI2010]所驼门王的宝藏(Tarjan+拓扑排序)
- BZOJ1924 [Sdoi2010]所驼门王的宝藏 【建图 + tarjan】
- 【bzoj1924】[Sdoi2010]所驼门王的宝藏(tarjan+STL+dp)
- bzoj 1718: [Usaco2006 Jan] Redundant Paths 分离的路径【tarjan】
- [HAOI2010][BZOJ2427] 软件安装|tarjan|树型dp
- [BZOJ]1924: [Sdoi2010]所驼门王的宝藏 强连通+DP
- bzoj1924 [Sdoi2010]所驼门王的宝藏
- BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP
- BZOJ 2125 浅谈沙漠中的顽强植物仙人掌图TarJan点双连通构型改造LCA在线最短路
- bzoj1924: [Sdoi2010]所驼门王的宝藏
- bzoj 1179: [Apio2009]Atm (spfa+tarjan)
- [BZOJ 2140] 稳定婚姻 Tarjan求强连通分量
- bzoj 2427: [HAOI2010]软件安装【tarjan+树形dp】
- bzoj2438 [中山市选2011]杀人游戏(tarjan缩点)