zoukankan      html  css  js  c++  java
  • bzoj2127happiness(最小割)

    一眼最小割。

    一种比较好想的建图方式如下:

    连源点表示学文,连汇点表示学理,然后adde(S,id(i,j),a[i][j]),adde(id(i,j),T,b[i][j]);对于相邻座位选择同一科的情况,建立新节点,然后若学文,则新点向T连一条流量为价值的边,然后两名同学向该点连接流量为inf的边。学理也是类似的。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define FOR(x,y) for(int i=1;i<=x;i++)for(int j=1;j<=y;j++)
    const int N=50100,M=3e5+7;
    using namespace std;
    int n,m,T,cnt,tot,ans,hd[N],lv[N],q[N],v[M],nxt[M],w[M];
    void adde(int x,int y,int z)
    {
        v[++cnt]=y,w[cnt]=z,nxt[cnt]=hd[x],hd[x]=cnt;
        v[++cnt]=x,w[cnt]=0,nxt[cnt]=hd[y],hd[y]=cnt;
    }
    bool bfs()
    {
        int qs=0,qe=1;
        memset(q,0,sizeof q);
        memset(lv,0,sizeof lv);
        q[0]=0,lv[0]=1;
        while(qs<qe)
        {
            int u=q[qs++];
            if(u==T)break;
            for(int i=hd[u];i;i=nxt[i])
            if(w[i]&&!lv[v[i]]){lv[v[i]]=lv[u]+1;q[qe++]=v[i];}
        }
        if(lv[T])return 1;return 0;
    }
    int dfs(int u,int low)
    {
        if(u==T||!low)return low;
        int sum=0;
        for(int i=hd[u];i;i=nxt[i])
        if(w[i]&&lv[v[i]]==lv[u]+1)
        {
            int tmp=dfs(v[i],min(w[i],low));
            sum+=tmp,low-=tmp,w[i]-=tmp,w[i^1]+=tmp;
            if(!low)return sum;
        }
        if(low)lv[u]=-1;
        return sum;
    }
    int id(int x,int y){return(x-1)*m+y;}
    int main()
    {
        scanf("%d%d",&n,&m);
        T=5*n*m+1,cnt=1,tot=n*m;
        int x;
        FOR(n,m)scanf("%d",&x),adde(0,id(i,j),x),ans+=x;
        FOR(n,m)scanf("%d",&x),adde(id(i,j),T,x),ans+=x;
        FOR(n-1,m)
        scanf("%d",&x),tot++,adde(0,tot,x),adde(tot,id(i,j),1e9),adde(tot,id(i+1,j),1e9),ans+=x;
        FOR(n-1,m)
        scanf("%d",&x),tot++,adde(tot,T,x),adde(id(i,j),tot,1e9),adde(id(i+1,j),tot,1e9),ans+=x;
        FOR(n,m-1)
        scanf("%d",&x),tot++,adde(0,tot,x),adde(tot,id(i,j),1e9),adde(tot,id(i,j+1),1e9),ans+=x;
        FOR(n,m-1)
        scanf("%d",&x),tot++,adde(tot,T,x),adde(id(i,j),tot,1e9),adde(id(i,j+1),tot,1e9),ans+=x;
        while(bfs())ans-=dfs(0,1e9);
        printf("%d",ans);
    }
    View Code
  • 相关阅读:
    学习篇之String()
    js之Math对象
    js之date()对象
    css之描点定位方式
    js详解之作用域-实例
    js精要之构造函数
    js精要之继承
    js精要之模块模式
    js精要之对象属性
    js精要之函数
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10953537.html
Copyright © 2011-2022 走看看