zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 55 G 最小割

    题意,一个图,选一个子图,使得 max(sum v[i] -sum a[i]) v[i] 边权,a[i]点权

    思路:

    最小割经典模型,我们把边和源相连流量v[i],点和汇向连流量a[i],中间的依赖用inf相连,那么这样的图最小割的含义就是“不选的边和选了的点的和”,那么这个值最小答案自然最大,sum v[i] - maxflow 就是答案了

    代码:

    #include<bits/stdc++.h>
    #define PB push_back
    #define X first
    #define Y second
    #define FIO std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    using namespace std;
    typedef long long ll;
    typedef double LD;
    typedef pair<int,int> pii;
    const int maxn=5e5+10;
    const ll inf=1e10+7;
    const int MAXN=3100;
    ll maze[MAXN][MAXN];
    ll gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];
    ll sap(int start,int end,int nodenum){
        memset(cur,0,sizeof(cur));
        memset(dis,0,sizeof(dis));
        memset(gap,0,sizeof(gap));
        ll u=pre[start]=start,maxflow=0,aug=-1;
        gap[0]=nodenum;
        while(dis[start]<nodenum){
        loop:
            for(int v=cur[u]; v<nodenum; v++)
                if(maze[u][v] && dis[u]==dis[v]+1){
                    if(aug==-1 || aug>maze[u][v])aug=maze[u][v];
                    pre[v]=u;
                    u=cur[u]=v;
                    if(v==end){
                        maxflow+=aug;
                        for(u=pre[u]; v!=start; v=u,u=pre[u]){
                            maze[u][v]-=aug;
                            maze[v][u]+=aug;
                        }
                        aug=-1;
                    }
                    goto loop;
                }
            int mindis=nodenum-1;
            for(int v=0; v<nodenum; v++)
                if(maze[u][v]&&mindis>dis[v]){
                    cur[u]=v;
                    mindis=dis[v];
                }
            if((--gap[dis[u]])==0)break;
            gap[dis[u]=mindis+1]++;
            u=pre[u];
        }
        return maxflow;
    }
    int n,m,x,y,z;
    ll a[MAXN];
    int main(){
        FIO;
        cin>>n>>m;
        ll ans=0;
        for(int i=1;i<=n;i++)cin>>a[i],maze[i][n+m+2]=a[i];
        for(int i=1;i<=m;i++){
            cin>>x>>y>>z;
            ans+=z;
            maze[n+i][x]=inf;
            maze[n+i][y]=inf;
            maze[0][n+i]=z;
        }
        cout<<ans-sap(0,n+m+2,n+m+3)<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Mybatis分页插件PageHelper使用
    JAVA面试笔记
    基于Fusioncharts的报表统计
    微信支付开发流程
    Java 使用 Jxl 实现 Excel 导入导出
    从navicat中导入sql文件过大:Got a packet bigger than 'max_allowed_packet' bytes
    一个故事告诉你比特币的原理及运作机制
    Linux和Windows下tomcat开机自启动设置
    Linux下安装MySQL
    ubuntu 13.10使用fcitx输入法
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672473.html
Copyright © 2011-2022 走看看