HDU6532 Chessboard(最小费用最大流)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#include<string>
using namespace std;
const int maxn=1e5;
const int inf=0x3f3f3f3f;
int N,M;
int head[maxn];
int tol;
struct node {
    int u;
    int v;
    int cap;
    int cost;
    int next;
}edge[maxn<<1];
int pre[maxn];
struct data {
    int t;
    int l;
}R[maxn],C[maxn];
bool cmp (data a,data b) {
    return a.l<b.l||a.l==b.l&&a.t<b.t;
}
void addedge (int u,int v,int cap,int cost) {
    edge[tol].u=u;
    edge[tol].v=v;
    edge[tol].cap=cap;
    edge[tol].cost=cost;
    edge[tol].next=head[u];
    head[u]=tol++;
}

int x[maxn],y[maxn],bx[maxn],by[maxn];
int nx,ny;
int r,c;
int xx[maxn],yy[maxn];



queue<int> q;
int d[maxn],limit[maxn];
int visit[maxn];
int maxflow,minCost;
int s,t;
bool spfa (int s,int t) {
    while (!q.empty()) q.pop();
    memset(d,0x3f,sizeof(d));
    memset(visit,0,sizeof(visit));
    d[s]=0;
    visit[s]=1;
    limit[s]=inf;
    q.push(s);
    while (!q.empty()) {
        int x=q.front();
        q.pop();
        for (int i=head[x];i!=-1;i=edge[i].next) {
            int v=edge[i].v;
            if (edge[i].cap&&d[x]+edge[i].cost<d[v]) {
                d[v]=d[x]+edge[i].cost;
                pre[v]=i;
                limit[v]=min(limit[x],edge[i].cap);
                if (!visit[v]) {
                    q.push(v);
                    visit[v]=1;
                }
            }
        }
        visit[x]=0;
    }
    return !(d[t]==inf);
}
void minCostMaxFlow () {
    maxflow=0,minCost=0;
    while (spfa(s,t)) {
        int u=t;
        maxflow+=limit[t];
        minCost+=limit[t]*d[t];
        while (u!=s) {
            edge[pre[u]].cap-=limit[t];
            edge[pre[u]^1].cap+=limit[t];
            u=edge[pre[u]^1].v;
        }
    }
}
int main () {
    scanf("%d",&N);
    memset(head,-1,sizeof(head));
    for (int i=1;i<=N;i++) {
        scanf("%d%d",&x[i],&y[i]);
        bx[i]=x[i];
        by[i]=y[i];
    }
    nx=ny=N;
    scanf("%d",&M);
    string s1;
    for (int i=0;i<M;i++) {
        int tx,ty;
        cin>>s1>>tx>>ty; 
        if (s1=="R") R[++r]={tx,ty};
        if (s1=="C") C[++c]={tx,ty}; 
    }
    int tmp=0;
    sort(R+1,R+r+1,cmp);
    for (int i=1;i<=r;i++) 
        if (tmp==0||R[i].t<R[tmp].t)
            R[++tmp]=R[i],bx[++nx]=R[i].t;
    r=tmp,tmp=0;
    sort(C+1,C+c+1,cmp);
    for (int i=1;i<=c;i++) 
        if (tmp==0||C[i].t<C[tmp].t)
            C[++tmp]=C[i],by[++ny]=C[i].t;
    c=tmp;
    sort(bx+1,bx+nx+1);
    nx=unique(bx+1,bx+nx+1)-(bx+1);
    sort(by+1,by+ny+1);
    ny=unique(by+1,by+ny+1)-(by+1);
    for (int i=1;i<=N;i++) {
        int tx=lower_bound(bx+1,bx+nx+1,x[i])-bx;
        int ty=lower_bound(by+1,by+ny+1,y[i])-by;
        addedge(tx,nx+1+ty,1,-i);
        addedge(nx+1+ty,tx,0,i);
    }
    memset(xx,0x3f,sizeof(xx));
    memset(yy,0x3f,sizeof(yy));
    for (int i=1;i<=r;i++) {
        int tx=lower_bound(bx+1,bx+nx+1,R[i].t)-bx;
        xx[tx]=min(xx[tx],R[i].l);
    }
    for (int i=1;i<=c;i++) {
        int ty=lower_bound(by+1,by+ny+1,C[i].t)-by;
        yy[ty]=min(yy[ty],C[i].l);
    }
    for (int i=1;i<=nx;i++) {
        addedge(i-1,i,xx[i],0);
        addedge(i,i-1,0,0);
    }
    for (int i=1;i<=ny;i++) {
        addedge(nx+1+i,nx+1+i-1,yy[i],0);
        addedge(nx+1+i-1,nx+1+i,0,0);
    }
    s=0;
    t=nx+1;
    minCostMaxFlow();
    printf("%d\n",-minCost);
} 

猜你喜欢

转载自www.cnblogs.com/zhanglichen/p/12537318.html
今日推荐