zoukankan      html  css  js  c++  java
  • 【Luogu】P2403所驼门王的宝藏(强连通分量)

      题目链接

      想到缩点后DP这题就迷之好做

      横天门就点向该行连一条边

      纵门就点向该列连一条边

      ziyou门直接枚举……map搞搞……话说ziyou门为啥是违规内容不让我发布?

      然后缩点,DP,1A

      不过写得迷之心累……想装死……

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #include<cstdlib>
    #include<map>
    #define maxn 2200010
    #define maxd 100020
    #define base r+c
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    int dfn[maxn],cnt;
    int stack[maxn],top;
    int col[maxn],ID;
    bool vis[maxn];
    int low[maxn];
    int size[maxn],sum[maxn];
    bool ext[maxn];
    int n,r,c;
    
    int ans;
    
    struct Pic{
        struct Edge{
            int next,to;
        }edge[maxn*2];
        int head[maxn],num;
        Pic(){memset(head,0,sizeof(head));}
        inline void add(int from,int to){
            edge[++num]=(Edge){head[from],to};
            head[from]=num;
        }
        void tarjan(int x){
            //printf("%d
    ",x);
            dfn[x]=low[x]=++cnt;
            vis[x]=1;    stack[++top]=x;
            for(int i=head[x];i;i=edge[i].next){
                int to=edge[i].to;
                if(dfn[to]==0){
                    tarjan(to);
                    low[x]=min(low[x],low[to]);
                }
                else if(vis[to])    low[x]=min(low[x],dfn[to]);
            }
            if(low[x]==dfn[x]){
                col[x]=++ID;    vis[x]=0;
                if(x>base)    size[ID]++;
                while(stack[top]!=x){
                    col[stack[top]]=ID;
                    vis[stack[top]]=0;
                    if(stack[top]>base)    size[ID]++;
                    top--;
                }
                top--;
            }
        }
        void dfs(int x){
            vis[x]=1;
            for(int i=head[x];i;i=edge[i].next){
                int to=edge[i].to;
                if(vis[to]){
                    sum[x]=max(sum[x],sum[to]);
                    continue;
                }
                dfs(to);
                sum[x]=max(sum[x],sum[to]);
            }
            sum[x]+=size[x];
            ans=max(ans,sum[x]);
            return;
        }
    }Old,New;
    
    map<long long,int>d;
    
    
    inline long long calc(long long i,long long j){    return (i-1)*c+j+base;    }
    
    struct Node{
        int x,y,id,opt;
    }q[maxd];
    
    int u[9]={0,-1,-1,0,1,1,1,0,-1};
    int w[9]={0,0,1,1,1,0,-1,-1,-1};
    
    int main(){
        n=read(),r=read(),c=read();
        for(int i=1;i<=n;++i){
            int x=read(),y=read(),opt=read();
            long long now=calc(x,y);
            ext[x]=ext[y+r]=ext[i+base]=1;
            Old.add(x,i+base);
            Old.add(y+r,i+base);
            q[i]=(Node){x,y,i+base,opt};
            d[now]=i+base;
        }
        for(int i=1;i<=n;++i){
            int opt=q[i].opt;
            if(opt==1)        Old.add(q[i].id,q[i].x);
            else if(opt==2)    Old.add(q[i].id,q[i].y+r);
            else{
                for(int j=1;j<9;++j){
                    int x=q[i].x+u[j],y=q[i].y+w[j];
                    if(x<1||x>r||y<1||y>c)    continue;
                    if(d.count(calc(x,y)))    Old.add(q[i].id,d[calc(x,y)]);
                }
            }
        }
        for(int i=1;i<=n+base;++i)
            if(ext[i]&&dfn[i]==0)    Old.tarjan(i);
        for(int i=1;i<=n+base;++i)
            for(int j=Old.head[i];j;j=Old.edge[j].next){
                int to=Old.edge[j].to;
                if(col[i]==col[to])    continue;
                New.add(col[i],col[to]);
            }
        for(int i=1;i<=ID;++i)
            if(vis[i]==0)    New.dfs(i);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    [leetcode]49. Group Anagrams变位词归类
    [leetcode]40. Combination Sum II组合之和(每元素限用一次)
    [leetcode]39. Combination Sum组合之和
    [leetcode]35. Search Insert Position寻找插入位置
    [leetcode]28. Implement strStr()实现strStr()
    [leetcode]25. Reverse Nodes in k-Group每k个节点反转一下
    [leetcode]24. Swap Nodes in Pairs交换节点对
    SVG基础知识 Adobe Illustrator绘制SVG
    Java静态方法和实例方法 java中的数组作为形参传入
    SVG可伸缩的矢量图形
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8862268.html
Copyright © 2011-2022 走看看