[BZOJ]1924: [Sdoi2010]所驼门王的宝藏 强连通+DP
2017-09-09 10:47
429 查看
题解:
思路很容易想到,就是缩点之后DP,问题是如何建图。见hzwer。代码:
#include<cstdio> #include<cstring> #include<map> #include<vector> #include<queue> #include<iostream> #include<algorithm> using namespace std; const int maxn=100010; int n,r,c,x[maxn],y[maxn],t[maxn],f[maxn],num[maxn]; int low[maxn],dfn[maxn],sta[maxn],top=0,id=0,belong[maxn],cnt=0; vector<int> A[1000005],B[1000005]; bool insta[maxn],mark[maxn*10]; struct p{int x,y,t,id;}a[maxn]; int tx[]= {0,0,1,-1,1,1,-1,-1}; int ty[]= {1,-1,0,0,-1,1,1,-1}; map<int,map<int,int> >M; struct Edge{int y,next;}e[maxn*8],e1[maxn*8]; int last[maxn],len=0; int last1[maxn],len1=0; void ins(int x,int y) { int t=++len; e[t].y=y; e[t].next=last[x]; last[x]=t; } void ins1(int x,int y) { int t=++len1; e1[t].y=y; e1[t].next=last1[x]; last1[x]=t; } bool in(int x,int y) { if(x&&y&&x<=r&&y<=c)return true; return false; } void Build() { for(int i=1;i<=r;i++) { int x=-1,S=A[i].size(); for(int j=0;j<S;j++) if(a[A[i][j]].t==1){x=A[i][j];break;} if(x!=-1) { for(int j=0;j<S;j++) { ins(x,A[i][j]); if(a[A[i][j]].t==1)ins(A[i][j],x); } } } for(int i=1;i<=c;i++) { int x=-1,S=B[i].size(); for(int j=0;j<S;j++) if(a[B[i][j]].t==2){x=B[i][j];break;} if(x!=-1) { for(int j=0;j<S;j++) { ins(x,B[i][j]); if(a[B[i][j]].t==2)ins(B[i][j],x); } } } for(int i=1;i<=n;i++) if(a[i].t==3) { for(int j=0;j<8;j++) { int nx=a[i].x+tx[j],ny=a[i].y+ty[j],k=M[nx][ny]; if(in(nx,ny)&&k)ins(a[i].id,k); } } } void dfs(int x) { low[x]=dfn[x]=++id; sta[++top]=x; insta[x]=true; for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(dfn[y]==-1) { dfs(y); low[x]=min(low[x],low[y]); } else if(insta[y])low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { int i; cnt++; do { i=sta[top--]; belong[i]=cnt; insta[i]=false; num[cnt]++; } while(i!=x); } } void Tarjan() { memset(insta,false,sizeof(insta)); memset(dfn,-1,sizeof(dfn)); for(int i=1;i<=n;i++) if(dfn[i]==-1)dfs(i); } queue<int>q; void ReBuild() { for(int x=1;x<=n;x++) for(int i=last[x];i;i=e[i].next) if(belong[x]!=belong[e[i].y])ins1(belong[x],belong[e[i].y]); } void DAGdp() { memset(insta,false,sizeof(insta)); for(int i=1;i<=cnt;i++)q.push(i),f[i]=num[i],insta[i]=true; while(!q.empty()) { int x=q.front(); q.pop(); insta[x]=false; for(int i=last1[x];i;i=e1[i].next) { int y=e1[i].y; if(y==x)continue; if(f[x]+num[y]>f[y]) { f[y]=f[x]+num[y]; if(!insta[y])q.push(y),insta[y]=true; } } } } int main() { scanf("%d%d%d",&n,&r,&c); for(int i=1;i<=n;i++) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].t); a[i].id=i; A[a[i].x].push_back(i); B[a[i].y].push_back(i); M[a[i].x][a[i].y]=i; } Build(); Tarjan(); ReBuild(); DAGdp(); int ans=0; for(int i=1;i<=cnt;i++)ans=max(ans,f[i]); printf("%d",ans); }
相关文章推荐
- [SDOI2010]BZOJ 1924所驼门王的宝藏-强连通分量-缩点-拓扑排序-dp
- [BZOJ 1924][Sdoi2010]所驼门王的宝藏
- BZOJ 1924: [Sdoi2010]所驼门王的宝藏 【tarjan】
- bzoj1924 [Sdoi2010]所驼门王的宝藏(tarjan缩点+拓扑排序+dp)
- 【SDOI2010】【BZOJ1924】所驼门王的宝藏
- BZOJ1924: [Sdoi2010]所驼门王的宝藏
- bzoj1924 [Sdoi2010]所驼门王的宝藏
- [BZOJ1924][Sdoi2010]所托门王的宝藏(缩点+DP)
- BZOJ1924: [Sdoi2010]所驼门王的宝藏
- 【BZOJ1924】【SDOI2010】所驼门王的宝藏
- bzoj1924: [Sdoi2010]所驼门王的宝藏
- BZOJ1924: [Sdoi2010]所驼门王的宝藏
- BZOJ1924 [Sdoi2010]所驼门王的宝藏 【建图 + tarjan】
- 【bzoj1924】[Sdoi2010]所驼门王的宝藏(tarjan+STL+dp)
- bzoj 1924 [Sdoi2010]所驼门王的宝藏(构图,SCC,DP)
- BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP
- bzoj 1924: [Sdoi2010]所驼门王的宝藏
- [bzoj 1924--SDOI2010]所驼门王的宝藏
- 【bzoj1924】【SDOI2010】所驼门王的宝藏
- bzoj 1924: [Sdoi2010]所驼门王的宝藏 (tarjan缩点+spfa)