bzoj 3961: [WF2011] Chips Challenge [Minimum cost and maximum flow]

Reference: https://blog.csdn.net/Quack_quack/article/details/50554032
Shenjian map series
First, turn the problem into full fill, and deduct at least a few to meet the conditions.
Consider the second condition first, enumerate f There are a few left for each row/column, then record the number of parts in each row and column (including filled in),
and then build a map
s to all rows with the flow of the number of parts in this row, and all columns to t to connect the flow For the edge of the number of parts in this column, the i row to the i column is connected to the edge with the flow f, which means that this row and column has the most flow f, and each (i, j) that can be deducted is connected to the i row and j column, because this should be as small as possible. And it needs to be counted, so add the value of 1 (other edges are 0), and then run the minimum cost maximum flow, there are two conditions for the judgment method: 1, the total flow is the total number of parts (full flow), because the selection sum does not The selection can flow on the map; 2, f b<=(sum-val) a
and the cost flow board I wrote before are all wrong? ? ?
And this doesn't seem to be able to dynamically add traffic, it can only enumerate the reconstruction map.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=105,inf=1e9;
int n,a,b,h[N],cnt,s,t,flo,val,dis[N],fr[N];
char p[N][N];
bool v[N],vis[N];
struct qwe
{
    int ne,no,to,va,c;
}e[N*N];
void add(int u,int v,int w,int c)
{
    cnt++;
    e[cnt].ne=h[u];
    e[cnt].no=u;
    e[cnt].to=v;
    e[cnt].va=w;
    e[cnt].c=c;
    h[u]=cnt;
}
void ins(int u,int v,int w,int c)
{//cerr<<u<<" "<<v<<" "<<w<<" "<<c<<endl;
    add(u,v,w,c);
    add(v,u,0,-c);
}
bool spfa()
{
    memset(v,0,sizeof(v));
    queue<int>q;
    for(int i=s;i<=t;i++)
        dis[i]=inf;
    dis[s]=0;
    v[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();//cerr<<u<<endl
        q.pop();
        v[u]=0;
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].va>0&&dis[e[i].to]>dis[u]+e[i].c)
            {
                dis[e[i].to]=dis[u]+e[i].c;
                fr[e[i].to]=i;
                if(!v[e[i].to])
                    v[e[i].to]=1,q.push(e[i].to);
            }
    }
    return dis[t]!=inf;
}
// void mcf()
// {
    // int x=inf;
    // for(int i=fr[t];i;i=fr[e[i].no])
        // x=min(x,e[i].va);//,cerr<<e[i].to<<" ";cerr<<endl;
    // flo+=x;
    // for(int i=fr[t];i;i=fr[e[i].no])
    // {
        // e[i].va-=x;
        // e[i^1].va+=x;
        // val+=x*e[i].c;
    // }
// }
inline int dfs(int u,int f) 
{
    if(u==t) return f;
    int us=0;
    vis[u]=1;
    for(int i=h[u];i&&us<f;i=e[i].ne)
        if(e[i].va>0&&!vis[e[i].to]&&dis[e[i].to]==dis[u]+e[i].c) 
        {
            int t=dfs(e[i].to,min(f,e[i].va));
            us+=t;
            val+=e[i].c*t ,
            e[i].va-=t,e[i^1].va+=t;
        }
    if(!us) 
        dis[u]=inf;
    vis[u]=0;
    return us;
}
int main()
{
    for(int cas=1;;cas++)
    {
        scanf("%d%d%d",&n,&a,&b);
        if(n+a+b==0)
            break;
        int sum=0,con=0,r[45],c[45],ans=-1;
        cnt=1,s=0,t=2*n+1,flo=0,val=0;
        memset(h,0,sizeof(h));
        memset(r,0,sizeof(r));
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",p[i]+1);
            for(int j=1;j<=n;j++)
                if(p[i][j]!='/')
                {
                    sum++,r[i]++,c[j]++;
                    if(p[i][j]=='C')
                        con++;
                    // else
                        // ins(i,j+n,1,1);
                }
        }
        // for(int i=1;i<=n;i++)
            // ins(s,i,r[i],0),ins(i+n,t,c[i],0);
        // int st=cnt+1;
        // for(int i=1;i<=n;i++)
            // ins(i,i+n,0,0);
        // while(spfa())
            // mcf();
        //cerr<<flo<<" "<<val<<endl;
        // if(flo==sum&&(sum-val)*a>=0)
            // ans=max(ans,sum-val);
        // for(int f=1;f<=n;f++)
        // {
            // for(int i=st;i<=cnt;i+=2)
                // e[i].va++;
            // while(spfa())
                // mcf();
            // cerr<<flo<<" "<<val<<endl;
            // if(flo==sum&&(sum-val)*a>=f*b)
                // ans=max(ans,sum-val);
        // }
        for(int f=0;f<=n;++f)
        {
            memset(h,0,sizeof h);
            flo=val=s=0;cnt=1;
            t=n*2+1;
            for(int i=1;i<=n;++i)
            {
                ins(s,i,r[i],0);
                ins(i+n,t,c[i],0);
                ins(i,i+n,f,0);
                for(int j=1;j<=n;++j)
                    if(p[i][j]=='.')
                        ins(i,j+n,1,1);
            }
            while(spfa())
                flo+=dfs(s,inf);
            if(flo==sum&&f*b<=(sum-val)*a)
                ans=max(ans,sum-val);
        }
        printf("Case %d: ",cas);
        if(ans==-1)
            puts("impossible");
        else
            printf("%d\n",ans-con);
    }
    return 0;
}
/*
2 1 1
/.
//
2 50 100
/.
C/
0 0 0
*/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324755833&siteId=291194637