zoukankan      html  css  js  c++  java
  • BZOJ 1924 && Luogu P2403 [SDOI2010]所驼门王的宝藏 恶心建图+缩点DP

    记住:map一定要这么用:

    if(mp[x[i]+dx[j]].find(y[i]+dy[j])!=mp[x[i]+dx[j]].end()) add(i,mp[x[i]+dx[j]][y[i]+dy[j]]);

      而不是

    R tmp=mp[x[i]+dx[j]][y[i]+dy[j]];
    if(tmp) add(i,tmp);

    别问我为什么QAQ

    建图:选定一个横天门,向在这一行上的横天门连无向边,剩下的门连有向边;纵寰门一样的方法

    用map判 自由_门 旁边八个点是否存在,存在就连边;

    最后tarjan缩点,用dp求最长路

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<map>
    #define R register int
    const int dx[]={0,1,1,1,0,-1,-1,-1},dy[]={1,1,0,-1,-1,-1,0,1};
    using namespace std;
    inline int g() {
        R ret=0; register char ch; while(!isdigit(ch=getchar())) ;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
    }
    #define pb(x) push_back(x) 
    int k,n,m,cnt=1,ind,cc,top,ans,num;
    int lst[100010],lst2[100010],x[100010],y[100010],op[100010],d[100010];
    int vr[1000010],nxt[1000010],fir[1000010],dfn[100010],scc[100010],stk[100010],low[100010],c[100010];
    vector<int>a[1000010],b[1000010];
    map<int,int> mp[1000010];
    bool vis[100010];
    inline void add(int u,int v) {if(u==v) return ;vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    inline void init() {
        for(R i=1;i<=n;++i) {
            R x=0,sz=a[i].size();
            for(R j=0;j<sz;++j) if(op[a[i][j]]==1) {x=a[i][j]; break;}
            for(R j=0;j<sz;++j) {add(x,a[i][j]); if(op[a[i][j]]==1) add(a[i][j],x);}
        }
        for(R i=1;i<=m;++i) {
            R x=0,sz=b[i].size();
            for(R j=0;j<sz;++j) if(op[b[i][j]]==2) {x=b[i][j]; break;}
            for(R j=0;j<sz;++j) {add(x,b[i][j]); if(op[b[i][j]]==2) add(b[i][j],x);}
        }
        for(R i=1;i<=k;++i) if(op[i]==3) for(R j=0;j<8;++j) 
            if(mp[x[i]+dx[j]].find(y[i]+dy[j])!=mp[x[i]+dx[j]].end()) add(i,mp[x[i]+dx[j]][y[i]+dy[j]]);void tarjan(int u) { low[u]=dfn[u]=++num; stk[++top]=u,vis[u]=true;
        for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
            if(!dfn[v]) {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            } else if(vis[v]) low[u]=min(low[u],dfn[v]);
        } if(low[u]==dfn[u]) {
            R tmp; ++cc;
            do tmp=stk[top],--top,vis[tmp]=false,c[tmp]=cc,++scc[cc]; while(tmp!=u);
        }
    }
    int vv[1000010],nn[1000010],ff[1000010];
    inline void addc(int u,int v) {vv[++cnt]=v,nn[cnt]=ff[u],ff[u]=cnt;}
    inline void solve() {
        cnt=1; for(R u=1;u<=k;++u) for(R i=fir[u];i;i=nxt[i]) 
            if(c[u]!=c[vr[i]]) addc(c[u],c[vr[i]]);
    }
    inline void dp(int u) { vis[u]=true;
        for(R i=ff[u];i;i=nn[i]) { R v=vv[i];
            if(!vis[v]) dp(v);
            d[u]=max(d[v],d[u]);
        } d[u]+=scc[u]; ans=max(d[u],ans);
    }
    signed main() {
        k=g(),n=g(),m=g();
        for(R i=1;i<=k;++i) {
            x[i]=g(),y[i]=g(),op[i]=g();
            mp[x[i]][y[i]]=i;
            a[x[i]].pb(i),b[y[i]].pb(i);
        } init(); for(R i=1;i<=k;++i) if(!dfn[i]) tarjan(i);
        solve(); memset(vis,false,sizeof(vis));
        for(R i=1;i<=cc;++i) if(!vis[i]) dp(i);
        printf("%d
    ",ans); return 0;
    }

    2019.04.21

    upd:5秒后 (发布时显示:博文中含有违规内容: 自_由_门! (并没有下划线)    ????不知所言)

  • 相关阅读:
    快排
    SQL实例
    14_可变字符串类和日期相关类
    13_String类的概述和使用
    c# json object Dictionary互转
    SQL Server 数据表给现有字段添加默认值或修改默认值
    SQL Server2008R2 死锁进程杀掉处理
    Sql Server 2008R2 查看SQL语句运行时间
    fatal: unable to access 'https://github.com/xxx': OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443
    idea出现了不能复制的问题
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10746423.html
Copyright © 2011-2022 走看看