Codeforces Round #366 (Div. 1) D Captain America 网络流

来源:互联网 发布:容迟网络 编辑:程序博客网 时间:2024/06/15 05:01

对于x和y我们建立二分图,一个点将相应的xy相连,那么我们也就是要给边分配红还是蓝,加入给T分个红,如果横坐标为x的点位z个那么|2*T-z|<=d, 也就是(z-d)/2<=t<=(z+d)/2,因为红蓝独立,所以我们只需要跑一遍上下界最大流即可。

#include<stdio.h>#include<iostream>#include<algorithm>#include<vector>#include<set>#include<string.h>#include<queue>#define maxn 200015#define inf 100000000using namespace std;struct pi{    int to;    int cost;    int rev;    int id;}pp;vector<pi >g[maxn];queue<int>q;int s,t;int line[maxn],leve[maxn];int min(int a,int b){    int p;    p=a;    if(b<a)        p=b;    return p;}void add(int a,int b,int cos,int id){    pp.to=b;    pp.cost=cos;    pp.id=id;    pp.rev=(int)g[b].size();    g[a].push_back(pp);    pp.to=a;    pp.cost=0;    pp.id=id;    pp.rev=(int)g[a].size()-1;    g[b].push_back(pp);    return ;}void insert(int a,int b,int l,int r){    add(s,b,l,-1);    add(a,b,r-l,-1);    add(a,t,l,-1);}void bfs(void){    q.push(s);    int p,f,i;    while(!q.empty())    {        p=q.front();        q.pop();        f=(int)g[p].size();        for(i=0;i<f;i++)        {            pi &e=g[p][i];            if(e.cost>0&&line[e.to]<0)            {                line[e.to]=line[p]+1;                q.push(e.to);            }        }    }    return ;}int dfs(int v,int f){    int p;    if(v==t)        return f;    for(int &i=leve[v];i<g[v].size();i++)    {        pi &e=g[v][i];        if(line[v]<line[e.to]&&e.cost>0)        {            p=dfs(e.to,min(f,e.cost));            if(p>0)            {                e.cost-=p;                g[e.to][e.rev].cost+=p;                return p;            }        }    }    return 0;}int dinic(){    int f;    int flow=0;    while(1)    {        memset(line,-1,sizeof(line));        memset(leve,0,sizeof(leve));        line[s]=0;        bfs();        if(line[t]<0)            return flow;        f=dfs(s,inf);        if(f==0)            continue;        flow+=f;        while((f=dfs(s,inf))>0)        {            flow+=f;        }    }}int x[maxn],y[maxn];struct in{    int x,y;}pp1[maxn];int l[maxn],r[maxn];int ans[maxn];set<int>xx,yy;int up[maxn],dow[maxn];int main(){    int n,m;    int u=0;    int r1,b1;    cin>>n>>m;    cin>>r1>>b1;    if(r1<b1) {        u=1;        swap(r1,b1);    }    for(int i=1;i<=n;i++){        scanf("%d%d",&pp1[i].x,&pp1[i].y);        x[i]=pp1[i].x;        y[i]=pp1[i].y;        xx.insert(x[i]);        yy.insert(y[i]);    }    sort(x+1,x+1+n);    sort(y+1,y+1+n);    for(int i=1;i<=n;i++){        pp1[i].x=lower_bound(x+1,x+1+n,pp1[i].x)-x;        pp1[i].y=lower_bound(y+1,y+1+n,pp1[i].y)-y;        add(pp1[i].x,pp1[i].y+n,1,i);        l[pp1[i].x]++;        r[pp1[i].y]++;    }    s=0;    t=2*n+3;    for(int i=1;i<=n;i++){        up[i]=l[i];        dow[i]=r[i];    }    for(int i=0;i<m;i++){        int p,x1,d;        scanf("%d%d%d",&p,&x1,&d);        if(p==1){            if(xx.find(x1)==xx.end()) continue;            x1=lower_bound(x+1,x+1+n,x1)-x;            up[x1]=min(up[x1],d);        }        else{            if(yy.find(x1)==yy.end()) continue;             x1=lower_bound(y+1,y+1+n,x1)-y;            dow[x1]=min(dow[x1],d);        }    }    for(int i=1;i<=n;i++){        int u0,d0;        u0=(l[i]+up[i])/2;        d0=(l[i]-up[i])/2;        if(2*d0<l[i]-up[i]) d0++;        if(u0<d0){            printf("-1\n");            return 0;        }        else {            if(d0<0) d0=0;            insert(2*n+1,i,d0,u0);        }        u0=(r[i]+dow[i])/2;        d0=(r[i]-dow[i])/2;        if(2*d0<r[i]-dow[i]) d0++;        if(u0<d0){            printf("-1\n");            return 0;        }        else {            if(d0<0) d0=0;            insert(n+i,2*n+2,d0,u0);        }    }    dinic();    add(2*n+2,2*n+1,inf,-1);    dinic();    int flag=0;    for(pi v:g[s]){        if(v.cost>0) flag=1;    }    if(flag) printf("-1\n");    else {        int w=0;        for(pi v:g[2*n+1]){            if(v.to==2*n+2){                w=v.cost;            }        }        long long s=(long long)w*r1+(long long)(n-w)*b1;        cout<<s<<endl;        for(int i=1;i<=n;i++){            for(pi v:g[i]){                if(v.cost==0&&v.id!=-1){                    ans[v.id]=1;                }            }        }        for(int i=1;i<=n;i++){            if(u==0){                if(ans[i]) printf("r");                else printf("b");            }            else{                if(ans[i]) printf("b");                else printf("r");            }        }        printf("\n");    }}


0 0
原创粉丝点击