• CF1288F Red-Blue Graph


    Link
    考虑上下界+费用流。
    对于左部点(u)
    如果颜色为(B),连((s,u,[1,+infty),0))
    如果颜色为(R),连((u,t,[1,+infty),0))
    如果颜色为(U),连((s,u,+infty,0),(u,t,+infty,0))
    对于右部点(u),我们将其颜色的(R/B)翻转然后类似于左部点建图即可。
    对于所有原图中的边((u,v)),连((u,v,1,b))((v,u,1,r))
    然后跑最小费用可行流。

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int N=407,M=2407,inf=40001;
    int s,t,tot=1,a[N],head[N],ver[M],next[M],edge[M],cost[M],flow[N],dis[N],inq[N],id[N];std::queue<int>q;char str[N];
    int read(){int x;scanf("%d",&x);return x;}
    void add(int u,int v,int f,int c)
    {
        ver[++tot]=v,next[tot]=head[u],head[u]=tot,edge[tot]=f,cost[tot]=c;
        ver[++tot]=u,next[tot]=head[v],head[v]=tot,edge[tot]=0,cost[tot]=-c;
    }
    int spfa()
    {
        memset(dis+1,0x3f,t<<2),q.push(s),inq[s]=1,dis[s]=0,flow[s]=inf,id[t]=-1;
        for(int i,u,v;!q.empty();)
        for(i=head[u=q.front()],q.pop(),inq[u]=0;i;i=next[i])
            if(edge[i]&&dis[v=ver[i]]>dis[u]+cost[i])
    	    if(dis[v]=dis[u]+cost[i],id[v]=i,flow[v]=std::min(flow[u],edge[i]),!inq[v])
    		q.push(v),inq[v]=1;
        return dis[t]<0;
    }
    int main()
    {
        int n1=read(),n2=read(),m=read(),r=read(),b=read(),ans=0;
        s=n1+n2+1,t=s+1;
        scanf("%s",str+1);
        for(int i=1;i<=n1;++i)
    	if(str[i]=='R') ans+=inf,add(i,t,1,-inf),add(i,t,inf,0);
    	else if(str[i]=='B') ans+=inf,add(s,i,1,-inf),add(s,i,inf,0);
    	else add(s,i,inf,0),add(i,t,inf,0);
        scanf("%s",str+1);
        for(int i=1;i<=n2;++i)
    	if(str[i]=='B') ans+=inf,add(i+n1,t,1,-inf),add(i+n1,t,inf,0);
    	else if(str[i]=='R') ans+=inf,add(s,i+n1,1,-inf),add(s,i+n1,inf,0);
    	else add(s,i+n1,inf,0),add(i+n1,t,inf,0);
        for(int i=1,u,v;i<=m;++i) u=read(),v=read(),add(u,v+n1,1,b),add(v+n1,u,1,r);
        for(int p;spfa();) for(ans+=dis[t]*flow[t],p=t;p^s;p=ver[id[p]^1]) edge[id[p]]-=flow[t],edge[id[p]^1]+=flow[t];
        if(ans>=inf) return puts("-1"),0;
        printf("%d
    ",ans);
        for(int i=1,st=4*(n1+n2)+1;i<=m;++i) putchar(edge[st+i*4-2]? 'B':edge[st+i*4]? 'R':'U');
    }
    
  • 相关阅读:
    Javascript中this关键字详解
    Chrome 中的 JavaScript 断点设置和调试技巧
    将Sublime Text3添加到右键菜单中
    sublime text 3如何安装插件和设置字号
    sublime text 侧边栏样式修改
    JS中关于clientWidth offsetWidth scrollWidth 等的含义
    scrollWidth,clientWidth,offsetWidth的区别
    JS中apply和call的用法
    JS中的call()和apply()方法
    JAVA-初步认识-第四章-函数-Demo练习
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12373747.html
Copyright © 2020-2023  润新知