zoukankan      html  css  js  c++  java
  • BZOJ3832Rally题解

    一道思维神题....

    我们像网络流一样加入原点S,与汇点T

    用f[i]表示原点到i的最长路,用g[i]表示i到汇点的最长路

    f数组与g数组都可以dp求出来的

    接下来考虑如何通过这些信息来维护删除某个点的最长路

    用拓扑序来删点

    我们先将所有g数组加入一个集合中,

    每次删点是就先将所有该点的入边的点的f[i]+g[x]从集合中删掉

    然后此时集合中最大值就是删除这个点的最优解

    然后再将每个点的出边i的f[x]+g[i]加入集合中

    可以发现这个集合可以用堆来维护

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<cstring>
    # include<algorithm>
    # include<queue>
    using namespace std;
    const int mn = 500005;
    struct Grap{
        struct edge{int to,next;};
        edge e[mn*2];
        int head[mn],edge_max;
        void add(int x,int y)
        {
            e[++edge_max].to=y;
            e[edge_max].next=head[x];
            head[x]=edge_max;
        }
    }A,B;
    int deg[mn*2],n,m,a[mn*2];
    int f[mn*2],g[mn*2];
    void topolpgy()
    {
        int tail=1,head=0;
        for(int i=1;i<=n;i++)
            if(!deg[i]) a[++head]=i;
        //printf("%d %d
    ",tail,head);
        while(tail<=head)
        {
            int u=a[tail];
            tail++;
            for(int i=A.head[u];i;i=A.e[i].next)
            {
                deg[A.e[i].to]--;
                if(!deg[A.e[i].to]) a[++head]=A.e[i].to;
            }
        }
    }
    struct Heap{
        int heap[mn*2],mark[mn*2],top;
        void ins(int x)
        {
            if(mark[x])
            {
                --mark[x];
                return ;
            }
            heap[++top]=x;
            int t=top;
            while(t>1)
            {
                if(heap[t]>heap[t>>1])
                    swap(heap[t],heap[t>>1]),t>>=1;
                else
                    break;
            }
        }
        void del(int x)
        {
            mark[x]++;
        }
        void Pop()
        {
            heap[1]=heap[top--];
            int t=2;
            while(t<=top)
            {
                if( t<top && heap[t+1]>heap[t] )
                    t++;
                if(heap[t]>heap[t>>1])
                    swap(heap[t],heap[t>>1]),t<<=1;
                else
                    break;
            }
        }
        int Top()
        {
            while(mark[heap[1]])
                mark[heap[1]]--,Pop();
            return heap[1];
        }
    }T;
    int main()
    {
        int x,y;
        A.edge_max=0,B.edge_max=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            A.add(x,y),B.add(y,x);
            deg[y]++;
        }
        topolpgy();
        /*for(int i=1;i<=n;i++)
            printf("%d ",a[i]);*/
        int ans=0,ans_len=0x3f3f3f3f;
        for(int i=1;i<=n;i++)
        {
            int u=a[i];
            f[u]=max(f[u],1);
            for(int j=A.head[u];j;j=A.e[j].next)
                f[A.e[j].to]=max(f[A.e[j].to],f[u]+1);
        }
        for(int i=n;i>=1;i--)
        {
            int u=a[i];
            g[u]=max(g[u],1);
            for(int j=A.head[u];j;j=A.e[j].next)
                g[u]=max(g[u],g[A.e[j].to]+1);
        }
        /*for(int i=1;i<=n;i++)
            printf("%d:%d %d
    ",i,f[i],g[i]);*/
        for(int i=1;i<=n;i++)
            T.ins(g[i]);
        T.ins(0);
        for(int i=1;i<=n;i++)
        {
            int u=a[i];
            for(int j=B.head[u];j;j=B.e[j].next)
            {
                T.del(f[B.e[j].to]+g[u]);
               //printf("%d ",f[B.e[j].to]+g[u]);
            }
            //printf("
    ");
            T.del(g[u]);
            if(T.Top()<ans_len)
            {
                ans_len=T.Top(),ans=u;
                //printf("%d ",T.Top());
            }
            for(int j=A.head[u];j;j=A.e[j].next)
            {
                T.ins(f[u]+g[A.e[j].to]);
                //printf("%d ",f[u]+g[B.e[j].to]);
            }
            T.ins(f[u]);
            //printf("%d
    ",ans_len-1);
        }
        printf("%d %d",ans,ans_len-1);
        return 0;
    }
  • 相关阅读:
    ACM ICPC 2008–2009 NEERC MSC A, B, C, G, L
    POJ 1088 滑雪 DP
    UVA 11584 最短回文串划分 DP
    POJ 2531 Network Saboteur DFS+剪枝
    UVa 10739 String to Palindrome 字符串dp
    UVa 11151 Longest Palindrome 字符串dp
    UVa 10154 Weights and Measures dp 降维
    UVa 10271 Chopsticks dp
    UVa 10617 Again Palindrome 字符串dp
    UVa 10651 Pebble Solitaire 状态压缩 dp
  • 原文地址:https://www.cnblogs.com/logeadd/p/9606574.html
Copyright © 2011-2022 走看看