zoukankan      html  css  js  c++  java
  • 太空飞行计划 最大权闭合图

    <span style="font-family: Arial, Helvetica, sans-serif;">选了一个点,必需选择其他点,故题意为求一个闭合图(闭合图:在一个图中,我们选取一些点构成集合,记为V,且集合中的出边(即集合中的点的向外连出的弧),所指向的终点(弧头)也在V中,则我们称V为闭合图。最大权闭合图即在所有闭合图中,集合中点的权值之和最大的V,我们称V为最大权闭合图。)</span>

    ,构图法:取起点s,连线去所有正权的点,所有负权的点连线到t,权值为绝对值,原图的边权值为inf,最大权=正权和-s-t最大流,最小割即为方案(最后一遍bfs求增广路后,vis[i]中可以到达的点(s集合中的,满流边过不去了)即为所取)。



    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<fstream>
    using namespace std;
    int n,m;int nume;int e[50000][3];int head[1005];
    const  int inf=100000;
    int vis[1005];int level[1005];
    bool bfs()
    {
        for(int i=0;i<=n+m+1;i++)
             vis[i]=level[i]=0;
        queue<int>q;q.push(0);vis[0]=1;
        while(!q.empty())
        {
            int cur=q.front();q.pop();
            for(int i=head[cur];i!=-1;i=e[i][1])
            {   int v=e[i][0];
                if(!vis[v]&&e[i][2]>0)
                {
                    level[v]=level[cur]+1;
                    if(v==n+1+m)return 1;
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
        return vis[n+1+m];
    }
    int dfs(int u,int minf)
    {
        if(minf==0||u==n+1+m)return minf;
        int sumf=0,f;
        for(int i=head[u];i!=-1&&minf;i=e[i][1])
        {
             int v=e[i][0];
            if(level[v]==level[u]+1&&e[i][2]>0)
            {
                f=dfs(v,minf<e[i][2]?minf:e[i][2]);
                e[i][2]-=f;e[i^1][2]+=f;
                minf-=f;sumf+=f;
            }
        }
        return sumf;
    }
    void addedge (int f,int to,int w)
    {
        e[nume][0]=to;e[nume][1]=head[f];head[f]=nume;
        e[nume++][2]=w;
        e[nume][0]=f;e[nume][1]=head[to];head[to]=nume;
        e[nume++][2]=0;
    }
    int dinic()
    {
        int sum=0;
        while(bfs())
           sum+=dfs(0,inf);
       return sum;
    }
    vector<int>vv;
    int main()
     {
         // ifstream cin("shuttle.in");
         //  ofstream out("shuttle.out");
        cin>>m>>n;
        for(int i=0;i<=m+n+1;i++)
            head[i]=-1;
            nume=0;
        int sum=0;int x,y,w;
         for(int i=1;i<=m;i++)
        {
            cin>>w;
            addedge(0,i,w);
            while(cin.peek()!='
    ')
            {
                cin>>y;
                addedge(i,y+m,inf);
            }
            sum+=w;
        }
        for(int i=m+1;i<=m+n;i++)
        {
            cin>>w;
            addedge(i,n+m+1,w);
        }
        int ans=sum-dinic();
        for(int i=1;i<n+m+1;i++)
           if(vis[i])vv.push_back(i);
        sort(vv.begin(),vv.end());
        int i;
        for(i=0;i<vv.size()&&vv[i]<=m;i++)
        {
            cout<<vv[i]<<" ";
        }
          cout<<endl;
         for(;i<vv.size();i++)
        {
            if(i==vv.size()-1)cout<<vv[i]-m<<endl;
           else cout<<vv[i]-m<<" ";
        }
        cout<<ans<<endl;
        return 0;
    }
    


  • 相关阅读:
    Eclipse 导入项目乱码问题(中文乱码)
    sql中视图视图的作用
    Java基础-super关键字与this关键字
    Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
    Android View和ViewGroup
    工厂方法模式(java 设计模式)
    设计模式(java) 单例模式 单例类
    eclipse乱码解决方法
    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
    【转】使用 Eclipse 调试 Java 程序的 10 个技巧
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925799.html
Copyright © 2011-2022 走看看