Codechef RIN 「Codechef14DEC」Course Selection 最小割离散变量模型

问题描述

提供中文版本好评,一直以为 Rin 是题目名字...

pdf

submit


题解

参考了 东营市胜利第一中学姜志豪 的《网络流的一些建模方法》(2016年信息学奥林匹克中国国家队候选队员论文)

读了之后很有感触,这里节选一段话:

最小割模型的本质是将点的集合 \(V\) 划分为两个点集 \(S,T\) ,使得 \(S \in S,T \in T\) ,且 \(S∩T=?\)

之前对最小割中边权为 \(INF\) 的边,一直理解为不允许被割,现在从另一个角度来认识,就是保证这条边所联通的两个点,不允许被划分到两个不同的集合中。



对于这道题,首先要进行一个脑洞的转化:得分最高->扣分最少

最小割一般解决的是最小化问题,这样就方便了。

然后运用离散变量模型:


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

//#define local

const int maxn=10100;
const int maxm=500007;
const int INF=0x3f3f3f3f;

int n,m,k,S,T;
int Head[maxn],to[maxm],Next[maxm],w[maxm],tot=1;

void addedge(int x,int y,int z){
    to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
}

void add(int x,int y,int z){
    addedge(x,y,z);addedge(y,x,0);
}

void Init(void){
    scanf("%d%d%d",&n,&m,&k);
}

int id(int x,int y){
    return (x-1)*m+y;
}

void Graph_build(void){
    S=n*m+1,T=S+1;
    for(int i=1,x;i<=n;i++){
        scanf("%d",&x);
        if(x==-1) x=INF;
        else x=200-x;
        add(S,id(i,1),x);
        for(int j=2;j<=m;j++){
            scanf("%d",&x);
            if(x==-1) x=INF;
            else x=200-x;
            add(id(i,j-1),id(i,j),x);
        }
        add(id(i,m),T,INF);
    }
    while(k--){
        int x,y;
        scanf("%d%d",&x,&y);
        add(S,id(y,1),INF);
        for(int i=2;i<=m;i++){
            add(id(x,i-1),id(y,i),INF);
        }
    }
}

int d[maxn];
int ans;

bool bfs(){
    memset(d,0,sizeof(d));
    queue<int>q;q.push(S);d[S]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=Head[x];i;i=Next[i]){
            if(d[to[i]]||!w[i]) continue;
            q.push(to[i]);d[to[i]]=d[x]+1;
            if(to[i]==T) return true;
        }
    }
    return false;
}

int dfs(int x,int flow){
    if(x==T) return flow;
    int rest=flow;
    for(int i=Head[x];i&&rest;i=Next[i]){
        if(d[to[i]]!=d[x]+1||!w[i]) continue;
        int k=dfs(to[i],min(rest,w[i]));
        if(!k) d[to[i]]=0;
        else{
            w[i]-=k,w[i xor 1]+=k;
            rest-=k;
        }
    }
    return flow-rest;
}

void Dinic(void){
    int t;
    while(bfs()){
        while(t=dfs(S,INF)) ans+=t;
    }
}

void Work(void){
    Graph_build();
    Dinic();
    ans=n*200-ans;
    double ouf=(double)ans/(double)n;
    printf("%.2f\n",ouf);
}

int main(){
    #ifdef local
        freopen("hzlbn.in","r",stdin);
    #endif
    Init();
    Work();
    return 0;
}

原文地址:https://www.cnblogs.com/liubainian/p/12057564.html

时间: 2024-11-09 05:09:41

Codechef RIN 「Codechef14DEC」Course Selection 最小割离散变量模型的相关文章

「CQOI2016」不同的最小割

「CQOI2016」不同的最小割 传送门 建出最小割树,把每一个点对的最小割抠出来 \(\text{unique}\) 一下就好了. 参考代码: #include <algorithm> #include <cstring> #include <cstdio> #define rg register #define file(x) freopen(x".in", "r", stdin), freopen(x".out&q

TopCoder12727 「SRM590Hard」FoxAndCity 最小割离散变量模型

问题描述 一张 \(N\) 个点无向图,边权都为 \(1\) ,添加若干条边,最小化 \(\sum\limits_{1 \le i \le n,i \in N_{+}}{(a_i-b_i)^2}\). \(b_i\) 是输入的, \(a_i\) 是 \(1\) 号点到 \(i\) 号点的最短路. submit 题解 添加边后, \(a_i\) 不会变小. \(a_i\) 就是离散变量. 原来有边的两个点 \(x,y\) 的最短路长度差值不会超过 \(1\) . \(\mathrm{Code}\)

【BZOJ 3232】圈地游戏 二分+SPFA判环/最小割经典模型

最小割经典模型指的是“一堆元素进行选取,对于某个元素的取舍有代价或价值,对于某些对元素,选取后会有额外代价或价值”的经典最小割模型,建立倒三角进行最小割.这个二分是显然的,一开始我也是想到了最小割的那个模型的但是我觉得他会不是一个圈我就否掉了,但是仔细想想的话会发现,如果是这样的话所得到的答案一定小于等于一个圈的答案(浓度),所以我们可定会得到最终答案,所以这样做是可以的,所以说要有宽松得正解的意识(泥沙俱下但沙子不影响我泥).当时我否掉最小割以后就立马去想费用流了,然后想到建图后发现那样建图虽

LG1344 「USACO4.4」Pollutant Control 最小割

问题描述 LG1344 题解 我太菜了,我一开始竟然没有看出这是个最小割裸题... 两个询问. 第一个询问,直接跑最小割就好了. 第二个询问,建图的时候边权建 \(1\) ,代表割掉这条边需要 \(1\) 的代价. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; template <typename Tp> void read(Tp &x){ x=0;char ch=1;int fh; while

【LA3487】最小割-经典模型 两种方法

题目链接 题意:A.B两个公司要买一些资源(他们自己买的资源不会重复),一个资源只能卖给一个公司.问最大收益. simple input 部分: 54 1 //买到1就给54元 15 2 33 3 2 4 5//买到4.5就给2元 题解:这道题是很经典的模型题,在这里给出两个方法. 方法一 把每个询问看成一个点,然后A的询问连源点,B的询问连汇点,如果AB间的某个询问有矛盾就在它们中间连一条无限大的边,ans=sum-最小割. // 方法一 把每个询问看成一个点,然后A的询问连源点,B的询问连汇

最小割在模型的应用

Maximize  ∑we - ∑pu 设 du 为u的边权和 s --> u g u-->v v-->u we u-->t g + 2*pu - du ans = (|V|*g - C[s,t])/2

「总结」网络流

网络流专题,总结一下. 一.最大流 一个网络图的最大流量,满足网络流的各种性质的情况下. 1.蜥蜴 简单的拆点,在点之间限流即可,设有$a_i$的高度,从$S$向有蜥蜴的柱子$x$连边,边缘的柱子向$T$连边,距离小于$i,j$. $$link(S,x,1),link(i_0,i_1,a_i),link(j,T,INF),link(i,j,INF)$$ 跑最大流就可以了. 2. 二.最小割 三.最大权闭合子图 根据最小割的模型,我们建立另外一个模型,关于物品是否被选择的模型. 对于一个物品来说,

【BZOJ2039】【2009国家集训队】人员雇佣 [最小割]

人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MB[Submit][Status][Discuss] Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定的金钱Ai,对于一些经理可能他做出的贡献不值得

【BZOJ 3144】 3144: [Hnoi2013]切糕 (最小割模型)

3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1764  Solved: 965 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R). 100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超