ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ 1924 Sdoi2010 所驼门王的宝藏

2019-09-14 16:41:41  阅读:383  来源: 互联网

标签:pb pp begin Sdoi2010 门王 1924 zy maxm mp


题目

题解:
对于同方向(横竖的),同行最近相邻的两个连边。每个关键点被左右最近横向点连边,被上下最近纵向点连边,自由门按题意连,没有宝藏的点不连边,求强连通分量缩点后跑拓扑排序即可。
我打的好长啊。

AC Code:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define maxn 1000006
#define maxm 100005
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
#define F first
#define S second
using namespace std;
 
int n,r,c,cnt,in[maxm];
vector<int>h[maxn],z[maxn];
vector<pii>zy;
 
map<pii,int>st;
vector<int>G[maxm],V[maxm];
 
int sta[maxm],dfn[maxm],low[maxm],bl[maxm],siz[maxm],dis[maxm],scc,tim;
void dfs(int u){
    dfn[u] = low[u] = ++tim;
    sta[++sta[0]] = u;
    for(int i=0,v;i<G[u].size();i++)
        if(!dfn[v=G[u][i]]){
            dfs(v);
            low[u] = min(low[u] , low[v]);
        }
        else if(!bl[v]){
            low[u] = min(low[u] , dfn[v]);
        }
    if(low[u] == dfn[u]){
        scc++;
        for(int t=-1;t!=u;){
            bl[t = sta[sta[0]--]] = scc;
            siz[scc]++;
        }
    }
}
 
int main(){
    scanf("%d%d%d",&n,&r,&c);   
    for(int i=1;i<=n;i++){
        int x,y,t;
        scanf("%d%d%d",&x,&y,&t);
        if(t == 1) h[x].pb(y);
        if(t == 2) z[y].pb(x);
        if(t == 3) zy.pb(mp(x,y));
        st[mp(x,y)] = ++cnt;
    }
    for(int i=1;i<=r;i++)
        if(!h[i].empty()){
            sort(h[i].begin(),h[i].end());
            for(int j=0,pr=0;j<h[i].size();j++){
                int p = h[i][j];
                if(j){
                    int npr = st[mp(i,p)];
                    G[npr].pb(pr),G[pr].pb(npr);
                    pr = npr;
                }
                else pr = st[mp(i,p)];
            }
        }
    for(int i=1;i<=c;i++)
        if(!z[i].empty()){
            sort(z[i].begin(),z[i].end());
            for(int j=0,pr=0;j<z[i].size();j++){
                int p = z[i][j];
                if(j){
                    int npr = st[mp(p,i)];
                    G[npr].pb(pr) , G[pr].pb(npr);
                    pr = npr; 
                }
                else pr = st[mp(p,i)];
            }
        }
    for(int i=0;i<zy.size();i++){
        int p = st[zy[i]];
        vector<int>::iterator t = lower_bound(h[zy[i].F].begin(),h[zy[i].F].end(),zy[i].S);
        if(t != h[zy[i].F].end())
            G[st[mp(zy[i].F,*t)]].pb(p);
        if(t != h[zy[i].F].begin()){
            t--;
            G[st[mp(zy[i].F,*t)]].pb(p);
        }
         
        t = lower_bound(z[zy[i].S].begin(),z[zy[i].S].end(),zy[i].F);
        if(t != z[zy[i].S].end())
            G[st[mp(*t,zy[i].S)]].pb(p);
        if(t != z[zy[i].S].begin()){
            t--;
            G[st[mp(*t,zy[i].S)]].pb(p);
        }
         
         
        for(int j=max(-1,1-zy[i].F);j<=min(1,r-zy[i].F);j++)
            for(int k=max(-1,1-zy[i].S);k<=min(1,c-zy[i].S);k++)
                if(j || k){
                    int u = zy[i].F + j , v = zy[i].S + k;
                    if(!st.count(mp(u,v))) continue;
                    G[p].pb(st[mp(u,v)]);
                }
    }
     
    for(int i=1;i<=r;i++)
        if(!h[i].empty()){
            for(int j=0;j<h[i].size();j++){
                int pp = h[i][j] , p = st[mp(i,pp)];
                vector<int>::iterator t = lower_bound(z[pp].begin(),z[pp].end(),i);
                if(t != z[pp].end())
                    G[st[mp(*t,pp)]].pb(p);
                if(t != z[pp].begin())      
                    t--,
                    G[st[mp(*t,pp)]].pb(p);
            }
        }
         
    for(int i=1;i<=c;i++)
        if(!z[i].empty()){
            for(int j=0;j<z[i].size();j++){
                int pp = z[i][j] , p = st[mp(pp,i)];
                vector<int>::iterator t = lower_bound(h[pp].begin(),h[pp].end(),i);
                if(t != h[pp].end())
                    G[st[mp(pp,*t)]].pb(p);
                if(t != h[pp].begin())
                    t--,
                    G[st[mp(pp,*t)]].pb(p);
            }
        }
     
    for(int i=1;i<=cnt;i++)
        if(!dfn[i])
            dfs(i);
             
    for(int i=1;i<=cnt;i++)
        for(int j=0,v;j<G[i].size();j++)
            if(bl[i] != bl[v=G[i][j]])
                V[bl[i]].pb(bl[v]) , in[bl[v]] ++;
     
    queue<int>q;
    for(int i=1;i<=scc;i++)
        if(!in[i])  
            q.push(i) , dis[i] = siz[i];
    int ans = 0;
    for(int u;!q.empty();){
        u = q.front() , q.pop();
        ans = max(ans , dis[u]);
        for(int j=0,v;j<V[u].size();j++){
            in[v=V[u][j]] --;
            dis[v] = max(dis[v] , dis[u] + siz[v]);
            if(!in[v]) q.push(v);
        }
    }
     
    printf("%d\n",ans);
}

标签:pb,pp,begin,Sdoi2010,门王,1924,zy,maxm,mp
来源: https://blog.csdn.net/qq_35950004/article/details/100829965

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有