加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

二元关系最小割

发布时间:2020-12-14 04:27:14 所属栏目:大数据 来源:网络整理
导读:处理一类问题: N个任务,M对二元组关系(x,y),求最小总花费,条件如下: 每个任务可以在机器A或机器B上完成,分别花费Ai、Bi。 若x,y同时在A上完成,花费C1(x,y)。 若x,y同时在B上完成,花费C2(x,y)。 若x在A、y在B上完成,花费C3(x,y)。 若x在B,y在A上完

处理一类问题:

N个任务,M对二元组关系(x,y),求最小总花费,条件如下:
每个任务可以在机器A或机器B上完成,分别花费Ai、Bi。
若x,y同时在A上完成,花费C1(x,y)。
若x,y同时在B上完成,花费C2(x,y)。
若x在A、y在B上完成,花费C3(x,y)。
若x在B,y在A上完成,花费C4(x,y)。

大概这种。

?

建模方法:

根据割集的定义列方程。

然后求解即可。

最后得到每条边的最终权值,由于每个这样的二元组都要最终做出选择。这样最后的最小割就包含了全局的所有的代价(就是加法交换律结合律就凑出来了)。

?

然后一些细节。

?

?

其实二元关系并不太常用,

对于比较容易解出答案的、某两个取不取会对答案造成影响的,就可以考虑这样建图。

是最小割建图的一个思路。

?

例题:

[国家集训队]人员雇佣

最大化收益的最小割,那么就把收益都算上,再减去为了符合题意而做出的最小的代价

直接列出方程:

a+b=0

a+f+d=3E

b+e+c=3E

c+d=2E

由于对称,直接e=f=2E,c=d=E,a=b=0即可。

这个题的好处是方程非常固定而且好解。

#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^‘0‘)
using namespace std;
typedef long long ll;
il void rd(ll &x){
    char ch;bool fl=false;
    while(!isdigit(ch=getchar()))(ch==-)&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1005;
const int V=1005;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll n,m,s,t;
int cur[V];
struct node{
    int nxt,to;
    ll w;
}e[2*(N*N*2+N*2)];
int hd[V],cnt=1;
int uu;
void add(int x,int y,ll w){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    e[cnt].w=w;
    hd[x]=cnt;
    
    e[++cnt].nxt=hd[y];
    e[cnt].to=x;
    e[cnt].w=0;
    hd[y]=cnt;
}
int d[V];
ll dfs(int x,ll flow){
    if(x==t) return flow;
    ll res=flow;
    for(reg i=cur[x];i&&res;i=e[i].nxt,cur[x]=i){
        int y=e[i].to;
        if(d[y]==d[x]+1&&e[i].w){
            ll k=dfs(y,min(res,e[i].w));
            if(!k) d[y]=0;
            e[i].w-=k;
            e[i^1].w+=k;
            res-=k;
        }
    }
    return flow-res;
}
int q[V],l,r;
bool bfs(){
    memset(d,0,sizeof d);
    l=1,r=0;
    q[++r]=s;
    d[s]=1;
    while(l<=r){
        int x=q[l++];
        for(reg i=hd[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(!d[y]&&e[i].w){
                d[y]=d[x]+1;
                q[++r]=y;
                if(y==t) return true;
            }
        }
    }
    return false;
}
ll E[N][N];
ll ans;
ll no[N];
ll a[N];
int main(){
    rd(n);
    s=0,t=n+1;
    for(reg i=1;i<=n;++i){
        rd(a[i]);
        add(i,t,a[i]);
    }
    for(reg i=1;i<=n;++i){
        for(reg j=1;j<=n;++j){
            rd(E[i][j]);
            ans+=E[i][j];
            if(E[i][j]&&i<j){
                add(i,j,(ll)2*E[i][j]);
                add(j,i,(ll)2*E[i][j]);
                no[i]+=E[i][j];
                no[j]+=E[i][j];
            }
        }
    }
    for(reg i=1;i<=n;++i){
        add(s,no[i]);
    }
    ll flow=0;
    ll lp=0,po=0;
    while(bfs()){
        for(reg i=0;i<=n+1;++i) cur[i]=hd[i];
        while(flow=dfs(s,inf)) 
        ans-=flow;    
    }
    printf("%lld ",ans);
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2018/12/16 16:53:09
*/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读