BZOJ:1924: [Sdoi2010]所驼门王的宝藏

Posted zzyer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ:1924: [Sdoi2010]所驼门王的宝藏相关的知识,希望对你有一定的参考价值。

题解:

Trajan缩点+DP最长路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1000009;
int n,r,c;
int ans;

vector<int>dx[maxn];
vector<int>dy[maxn];
int inx[maxn],iny[maxn],inz[maxn];

vector<int>G1[maxn];
vector<int>G2[maxn];

int dfsclock,scccnt;
int pre[maxn],lowlink[maxn],sccno[maxn];
int Sta[maxn],top;
int Dfs(int u){
	pre[u]=lowlink[u]=(++dfsclock);
	Sta[++top]=u;
	for(int i=0;i<G1[u].size();++i){
		int v=G1[u][i];
		if(!pre[v]){
			Dfs(v);
			lowlink[u]=min(lowlink[u],lowlink[v]);
		}else if(!sccno[v]){
			lowlink[u]=min(lowlink[u],pre[v]);
		}
	}
	if(lowlink[u]==pre[u]){
		++scccnt;
		for(;;){
			int x=Sta[top--];
			sccno[x]=scccnt;
			if(x==u)break;
		}
	}
}

int v[maxn];
int Trajan(){
	for(int i=1;i<=n;++i){
		if(!pre[i])Dfs(i);
	}
	for(int i=1;i<=n;++i){
		v[sccno[i]]++;
		for(int j=0;j<G1[i].size();++j){
			if(sccno[i]!=sccno[G1[i][j]]){
				G2[sccno[i]].push_back(sccno[G1[i][j]]);
			}
		}
	}
}

int f[maxn];
int dp(int x){
	if(f[x])return 0;
	for(int i=0;i<G2[x].size();++i){
		dp(G2[x][i]);
		f[x]=max(f[x],f[G2[x][i]]);
	}
	f[x]+=v[x];
}

int abs(int x){
	if(x<0)return -x;
	else return x;
}

int minit(){
	top=dfsclock=scccnt=ans=0;
	memset(f,0,sizeof(f));
	memset(v,0,sizeof(v));
	memset(pre,0,sizeof(pre));
	memset(lowlink,0,sizeof(lowlink));
	memset(sccno,0,sizeof(sccno));
	for(int i=0;i<=max(r,c)+1;++i){
		dx[i].clear();dy[i].clear();G1[i].clear();G2[i].clear();
	}
}

int main(){
	scanf("%d%d%d",&n,&r,&c);
	//minit();
	for(int i=1;i<=n;++i){
		scanf("%d%d%d",&inx[i],&iny[i],&inz[i]);
		dx[inx[i]].push_back(i);
		dy[iny[i]].push_back(i);
	}
	for(int i=1;i<=n;++i){
		if(inz[i]==1){
			for(int j=0;j<dx[inx[i]].size();++j){
				G1[i].push_back(dx[inx[i]][j]);
			}
		}
		if(inz[i]==2){
			for(int j=0;j<dy[iny[i]].size();++j){
				G1[i].push_back(dy[iny[i]][j]);
			}
		}
		if(inz[i]==3){
			for(int j=0;j<dx[inx[i]-1].size();++j){
				if(abs(iny[dx[inx[i]-1][j]]-iny[i])<=1){
					G1[i].push_back(dx[inx[i]-1][j]);
				}
			}
			for(int j=0;j<dx[inx[i]].size();++j){
				if(abs(iny[dx[inx[i]][j]]-iny[i])==1){
					G1[i].push_back(dx[inx[i]][j]);
				}
			}
			for(int j=0;j<dx[inx[i]+1].size();++j){
				if(abs(iny[dx[inx[i]+1][j]]-iny[i])<=1){
					G1[i].push_back(dx[inx[i]+1][j]);
				}
			}
		}
	}
	Trajan();
	for(int i=1;i<=n;++i){
		dp(i);
		ans=max(ans,f[i]);
	}
	printf("%d\n",ans);
	return 0;
}

  

以上是关于BZOJ:1924: [Sdoi2010]所驼门王的宝藏的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1924: [Sdoi2010]所驼门王的宝藏 题解

BZOJ:1924: [Sdoi2010]所驼门王的宝藏

bzoj 1924: [Sdoi2010]所驼门王的宝藏

bzoj1924: [Sdoi2010]所驼门王的宝藏

BZOJ 1924 Sdoi2010 所驼门的宝藏

BZOJ-1924所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP