BZOJ 1924 Sdoi2010 所驼门的宝藏

Posted zhangenming

tags:

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

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

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1380  Solved: 603
[Submit][Status][Discuss]

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

HINT

测试点编号 N R C 1 16 20 20 2 300 1,000 1,000 3 500 100,000 100,000 4 2,500 5,000 5,000 5 50,000 5,000 5,000 6 50,000 1,000,000 1,000,000 7 80,000 1,000,000 1,000,000 8 100,000 1,000,000 1,000,000 9 100,000 1,000,000 1,000,000 10 100,000 1,000,000 1,000,000

Source

图的长和宽很大,所以我们不可能把所有点都连边

我们发现没有传送门的点是没有意义的

所以这需要在有传送门的点之间连边即可

一二操作好处理,三号操作的话,因为长和宽很大数组肯定开不下

我们用map去记录周围八个点是否有穿送门即可

细节看代码,记得vector的内存是根据实际用多少来算的

技术分享图片
  1 #include <bits/stdc++.h>
  2 #define ll long long
  3 #define eps 1e-7
  4 using namespace std;
  5 inline int read(){
  6     int x=0;int f=1;char ch=getchar();
  7     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
  8     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
  9     return x*f;
 10 }
 11 const int MAXN=1e5+10;
 12 int dx[8]={0,0,1,1,1,-1,-1,-1};
 13 int dy[8]={1,-1,0,1,-1,0,1,-1};
 14 vector < int > a[1000010],b[1000010];
 15 map < int,int > mp[1000010];
 16 struct node{
 17     int y,next;
 18 }e[1000010],E[1000010];
 19 int dfs_clock=0,linkk[MAXN],dfn[MAXN],low[MAXN],ans,k,n,m,f[MAXN],x[MAXN],y[MAXN],opt[MAXN],len,Linkk[MAXN],stark[MAXN],top,tot,ine[MAXN],sum[MAXN];
 20 bool vis[MAXN];
 21 inline void insert(int xx,int yy){
 22     if(xx==yy) return;
 23     e[++len].y=yy;e[len].next=linkk[xx];linkk[xx]=len;
 24 }
 25 inline void insertt(int xx,int yy){
 26     E[++len].y=yy;E[len].next=Linkk[xx];Linkk[xx]=len;
 27 }
 28 inline void tarjin(int st){
 29     dfn[st]=low[st]=++dfs_clock;
 30     stark[++top]=st;vis[st]=1;
 31     for(int i=linkk[st];i;i=e[i].next){
 32         if(!dfn[e[i].y]){
 33             tarjin(e[i].y);
 34             low[st]=min(low[st],low[e[i].y]);
 35         }
 36         else if(vis[e[i].y]) low[st]=min(low[st],dfn[e[i].y]);
 37     }
 38     if(low[st]==dfn[st]){
 39         tot++;int k;
 40         do{
 41             k=stark[top--];
 42             ine[k]=tot;
 43             sum[tot]++;
 44             vis[k]=0;
 45         }while(k!=st);
 46     }
 47 }
 48 void init(){
 49     k=read();n=read();m=read();
 50     for(int i=1;i<=k;i++){
 51         x[i]=read();y[i]=read();opt[i]=read();
 52         mp[x[i]][y[i]]=i;
 53         a[x[i]].push_back(i);
 54         b[y[i]].push_back(i);
 55     }
 56 }
 57 void build(){
 58     for(int i=1;i<=n;i++){
 59         int x=0;int t=a[i].size();
 60         for(int j=0;j<t;j++){
 61             if(opt[a[i][j]]==1) {x=a[i][j];break;}
 62         }
 63         for(int j=0;j<t;j++){
 64             insert(x,a[i][j]);
 65             if(opt[a[i][j]]==1) insert(a[i][j],x);
 66         }
 67     }
 68     for(int i=1;i<=m;i++){
 69         int y=0;int t=b[i].size();
 70         for(int j=0;j<t;j++){
 71             if(opt[b[i][j]]==2) {y=b[i][j];break;}
 72         }
 73         for(int j=0;j<t;j++){
 74             insert(y,b[i][j]);
 75             if(opt[b[i][j]]==2) insert(b[i][j],y);
 76         }
 77     }
 78     for(int i=1;i<=k;i++){
 79         if(opt[i]==3){
 80             for(int j=0;j<8;j++){
 81                 int t=mp[x[i]+dx[j]][y[i]+dy[j]];
 82                 if(t) insert(i,t);
 83             }
 84         }
 85     }
 86 }
 87 void rebuild(){
 88     len=0;
 89     for(int i=1;i<=k;i++){
 90         for(int j=linkk[i];j;j=e[j].next){
 91             if(ine[i]!=ine[e[j].y]){
 92                 insertt(ine[i],ine[e[j].y]);
 93             }
 94         }
 95     }
 96 }
 97 inline void dp(int st){
 98     vis[st]=1;
 99     for(int i=Linkk[st];i;i=E[i].next){
100         if(!vis[E[i].y]) dp(E[i].y);
101         f[st]=max(f[E[i].y],f[st]);
102     }
103     f[st]+=sum[st];
104     ans=max(ans,f[st]);
105 }
106 void solve(){
107     build();
108     for(int i=1;i<=k;i++){
109         if(!dfn[i]) tarjin(i);
110     }
111     rebuild();
112     memset(vis,0,sizeof(vis));
113     for(int i=1;i<=tot;i++){
114         if(!vis[i]) dp(i);
115     }
116     cout<<ans<<endl;
117 }
118 int main(){
119     init();
120     solve();
121     return 0;
122 }
View Code

 













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

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

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

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

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

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

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