mxqz刚学网络流,调了两天,已破防
查看原帖
mxqz刚学网络流,调了两天,已破防
311306
dk_qwq楼主2023/4/27 20:24

RT,菜菜,样例都调不出来了,建边已经和第二篇题解一模一样了,cost也一样,但不知道为什么check没过


#include<iostream>
#include<cstdio>
#include<vector>
#define pb push_back
#include<cstring>
#include<queue>
using namespace std;
namespace INPUT{
    char buf[1<<20],*p1,*p2;
    #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
}
using namespace INPUT;
template<typename T>
inline T read(){
    T x=0,p=1;
    char ch=gc();
    for(;ch<'0'||ch>'9';ch=gc())
        if(ch=='-') p=-1;
    for(;ch>='0'&&ch<='9';ch=gc())
        x=(x<<3)+(x<<1)+(ch^48);
    return x*p;
}
const int N=1e3+5;
#define ll long long
struct Edge{
    int u,v;
    ll cap,flow,cost;
    Edge(int u,int v,ll cap,ll flow,ll cost):
        u(u),v(v),cap(cap),flow(flow),cost(cost){}
};
vector<Edge>edges;
vector<int>G[N];
void add(int u,int v,ll cap,ll cost){
    edges.pb(Edge(u,v,cap,0,cost));
    edges.pb(Edge(v,u,0,0,-cost));
    int m=edges.size();
    G[u].pb(m-2),G[v].pb(m-1);
}
bool vis[N];
ll d[N];
int n,src,des;
queue<int>q;
bool spfa(){
    for(int i=0;i<N;i++) d[i]=1e18;
    q.push(src),d[src]=0;
    while(!q.empty()){
        int u=q.front();q.pop();
        vis[u]=false;
        for(auto i:G[u]){
            Edge ed=edges[i];
            if(d[ed.v]>d[u]+ed.cost&&ed.cap>ed.flow){
                d[ed.v]=d[u]+ed.cost;
                if(!vis[ed.v]) q.push(ed.v),vis[ed.v]=true;
            }
        }
    }
    return d[des]<0;
}
int cur[N];
ll DFS(int u,ll a,ll &cost){
    if(u==des||a==0) return a;
    vis[u]=true;
    ll flow=0,f;
    for(int &i=cur[u];i<G[u].size();i++){
        int x=G[u][i];
        Edge ed=edges[x];
        if(!vis[ed.v]&&d[ed.v]==d[u]+ed.cost){
            f=DFS(ed.v,min(a,ed.cap-ed.flow),cost);
            edges[x].flow+=f,edges[x^1].flow-=f;
            flow+=f,a-=f;
            cost+=f*ed.cost;
            if(!a) break;
        }
    }
    vis[u]=false;
    return flow;
}
const int Inf=1e9;
ll Mincost(ll &cost){
    ll flow=0,f;
    while(spfa()){
        memset(cur,0,sizeof(cur));
        while((f=DFS(src,Inf,cost))) flow+=f;
    }
    return flow;
}
bool check(){
    for(int i=0;i<edges.size();i+=2){
        if(edges[i].cost==Inf&&edges[i^1].flow>0) return false;
        if(edges[i].cost==-Inf&&edges[i].flow>0) return false;
    }
    return true;
}
const int M=35;
int R,C;
int id[2][M][M];
int tpe[M][M];
int c[M][M],r[M][M];//-  |
int sc[M][M],sr[M][M];
int pre1[M][M],pre2[M][M];
int val[M][M];
ll ans;
int main(){
    // freopen("P4486.in","r",stdin);
    // freopen("P4486.out","w",stdout);
    R=read<int>(),C=read<int>();
    int t=0;
    for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) {
        tpe[i][j]=read<int>();
        if(tpe[i][j]==1||tpe[i][j]==3) id[0][i][j]=++t;
        if(tpe[i][j]==2||tpe[i][j]==3) id[1][i][j]=++t;
    }
    src=++t,des=++t;
    for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) {
        if(tpe[i][j]==1||tpe[i][j]==3) r[i][j]=read<int>();
        if(tpe[i][j]==2||tpe[i][j]==3) c[i][j]=read<int>();
        if(tpe[i][j]==4) val[i][j]=read<int>();
    }
    for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) {
        if(tpe[i][j]==1||tpe[i][j]==3) {
            for(int k=i+1;k<=R;k++){
                if(tpe[k][j]!=4) break;
                pre1[k][j]=id[0][i][j];
                sr[i][j]++;
            }
        }
        if(tpe[i][j]==2||tpe[i][j]==3) {
            for(int k=j+1;k<=C;k++){
                if(tpe[i][k]!=4) break;
                pre2[i][k]=id[1][i][j];
                sc[i][j]++;
            }
        }
    }
    for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) {
        if(tpe[i][j]==1||tpe[i][j]==3) {
            int x=read<int>();if(x==-1) x=Inf;
            ans+=(ll)abs(sr[i][j]-r[i][j])*x;
            if(sr[i][j]<r[i][j]) add(src,id[0][i][j],r[i][j]-sr[i][j],-x);
            add(src,id[0][i][j],Inf,x);
        }
        if(tpe[i][j]==2||tpe[i][j]==3) {
            int x=read<int>();if(x==-1) x=Inf;
            ans+=(ll)abs(sc[i][j]-c[i][j])*x;
            if(sc[i][j]<c[i][j]) add(id[1][i][j],des,c[i][j]-sc[i][j],-x);
            add(id[1][i][j],des,Inf,x);
        }
        if(tpe[i][j]==4) {
            int x=read<int>();if(x==-1) x=Inf;
            ans+=(ll)abs(val[i][j]-1)*x;
            if(val[i][j]>1) add(pre1[i][j],pre2[i][j],val[i][j]-1,-x);
            add(pre1[i][j],pre2[i][j],Inf,x);
        }
    }
    n=des+1;
    ll cost=0;Mincost(cost);
    if(!check()) puts("-1");
    else printf("%lld\n",ans+cost);
}

2023/4/27 20:24
加载中...