Codechef RIN "Codechef14DEC" Course Selection minimal cut discrete variable model

Problem Description

Provide Chinese version of praise, always I thought that Rin is the name of the subject ...

pdf

submit


answer

Reference to the first victory in Dongying City High School Jiang Zhihao's "Some network flow modeling" (2016 Olympiad in Informatics Chinese national team candidate papers)

After reading a very touching passage excerpt here:

Model is essentially the minimum cut set of points \ (V \) is divided into two set points \ (S, T \) , so \ (S \ in S, T \ in T \) , and \ (S∩T = ∅ \)

Before minimal cut in the right side is \ (INF \) side, has been interpreted to prevent being cut, now to understand from another perspective, it is to ensure that the two points on this side of the Unicom, not allowed to be divided into two different collection.


For this question, we must first conduct a brain-hole transformation: the highest score -> Minimum deduction

Minimum cut general solution is to minimize the problem, so convenient.

Then use discrete variables in the model:


\(\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;
}

Guess you like

Origin www.cnblogs.com/liubainian/p/12057564.html