zoukankan      html  css  js  c++  java
  • [网络流24题] 太空飞行计划

    (我真是越学越回去了,打回胎重造吧)
    经典的最大权闭合子图模型,关键是怎么输出方案。用ISAP的话很显然需要额外搜一遍找出所有与S联通的点就是答案。
    笔者第一眼居然以为判下流量就行 傻逼实锤

    #include <bits/stdc++.h>
    using namespace std;
    
    
    const int N = 16384, MAXN = 262144;
    #define reset(x) memset(x,0,sizeof x)
    struct graph
    {
        int n,m,M,S,T,head[N],cur[N],dep[N],gap[N],q[N],vis[N];
        long long ans;
        struct ed
        {
            int to,nxt,val,src;
        } edge[MAXN];
        void init(int n0,int m0,int S0,int T0)
        {
            n=n0,m=m0,S=S0,T=T0,M=1,reset(gap);
            reset(head),reset(cur),reset(dep),reset(q);
        }
        int _make(int u,int v,int w)
        {
            edge[++M]=(ed) {v,head[u],w,w},head[u]=M;
            return M;
        }
        int make(int u,int v,int w)
        {
            _make(v,u,0);
            return _make(u,v,w);
        }
        int dfs(int u,int mx)
        {
            if (u==T)
                return mx;
            int num=0,f;
            for (int &i=cur[u],v; i; i=edge[i].nxt)
                if (dep[v=edge[i].to]==dep[u]-1 && (f=edge[i].val))
                    if (edge[i].val-=(f=dfs(v,min(mx-num,f))), edge[i^1].val+=f, (num+=f)==mx)
                        return num;
            if (!--gap[dep[u]++])
                dep[S]=n+1;
            return ++gap[dep[u]],cur[u]=head[u],num;
        }
        void _dfs(int p)
        {
            vis[p]=1;
            if(p==T)
                return;
            for(int i=head[p]; i; i=edge[i].nxt)
            {
                int q=edge[i].to;
                if(!vis[q] && edge[i].val)
                    _dfs(q);
            }
        }
        void solve()
        {
            for (int i=1; i<=n; ++i)
                cur[i]=head[i];
            ans=0;
            for (gap[0]=n; dep[S]<=n; ans+=dfs(S,0x7fffffff));
        }
    } g;
    
    int n,m,t1,t2,t3,t4,tot,lab[100005],mac[100005];
    char str[100005];
    
    int main()
    {
        cin>>n>>m;
        cin.getline(str,1e+5);
        g.init(n+m+2,0,n+m+1,n+m+2);
        for(int i=1; i<=n; i++)
        {
            cin.getline(str,1e+5);
            stringstream ss(str);
            ss>>t1;
            tot+=t1;
            lab[i] = g.make(n+m+1,i,t1);
            while(ss>>t1)
            {
                g.make(i,n+t1,1e+9);
            }
        }
        for(int i=1; i<=m; i++)
        {
            cin>>t1;
            mac[i] = g.make(n+i,n+m+2,t1);
        }
        g.solve();
        g._dfs(n+m+1);
        int flag = 0;
        for(int i=1; i<=n; i++)
        {
            if(g.vis[i])
            {
                if(flag)
                    cout<<" ";
                flag=1;
                cout<<i;
            }
        }
        cout<<endl;
        flag = 0;
        for(int i=1; i<=m; i++)
        {
            if(g.vis[i+n])
            {
                if(flag)
                    cout<<" ";
                flag=1;
                cout<<i;
            }
        }
        cout<<endl;
        cout<<tot-g.ans<<endl;
    }
    
  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/mollnn/p/11717834.html
Copyright © 2011-2022 走看看