BJ模拟:Mr. Panda and Tube Master(费用流)

本文介绍了一种使用最大费用最大流算法解决特定匹配问题的方法。通过将原图中的节点进行黑白染色并拆分为两个节点,利用最大费用流算法找到最优匹配方案。适用于需要求解带权匹配的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

题解:
考虑黑白染色,把原来的点拆为两个点,令黑点左右连边,白点上下连边做最大匹配。 如果不是必需点,则自己和自己连边。

显然任意合法方案都对应着一组匹配,而任意一组匹配都可以还原出一个方案。 我们做最大费用最大流即可。

#include  <bits/stdc++.h>
using namespace std;
inline int rd(int x=0) {return (scanf("%d",&x),x);}
const int N=1e3+50,M=2e5+50,L=25,INF=0x3f3f3f3f;
int n,m,src,des,cx[L][L],cy[L][L],ms[L][L],gg; queue <int> q;
int g[N],nt[M],vt[M],c[M],w[M],ec,dis[M],vis[M],exi[M],vs,cur[N];
inline int id(int x,int y,int t) {return (x-1)*m+y+(t==2)*n*m;}
inline void init()  {memset(g+1,0,sizeof(int)*des); ec=1; gg=0;}
inline void add(int x,int y,int cc,int ww) {
    nt[++ec]=g[x]; g[x]=ec; vt[ec]=y; c[ec]=cc; w[ec]=ww;
    nt[++ec]=g[y]; g[y]=ec; vt[ec]=x; c[ec]=0; w[ec]=-ww;
}
inline bool spfa() {
    for(int i=1;i<=des;i++) dis[i]=-INF;
    q.push(src); dis[src]=0;
    while(!q.empty()) {
        int u=q.front(); q.pop(); exi[u]=0;
        for(int e=g[u];e;e=nt[e]) {
            if(!c[e] || dis[vt[e]]>=dis[u]+w[e]) continue;
            dis[vt[e]]=dis[u]+w[e]; if(!exi[vt[e]]) exi[vt[e]]=1, q.push(vt[e]);
        }
    } return dis[des]>-INF;
}
inline int dinic(int x,int f,int cost) {
    if(x==des) {gg+=cost*f; return f;}
    int rs=0; vis[x]=vs;
    for(int &e=cur[x];e;e=nt[e]) {
        if(!c[e] || vis[vt[e]]==vs || (dis[vt[e]]!=dis[x]+w[e])) continue;
        int o=dinic(vt[e],min(f-rs,c[e]),cost+w[e]);
        rs+=o; c[e]-=o; c[e^1]+=o;
        if(rs==f) return rs;
    } return dis[x]=-INF, rs;
}
inline int maxflow() {
    int rs=0;
    while(spfa()) {
        int t; ++vs, memcpy(cur+1,g+1,sizeof(int)*des);
        while((t=dinic(src,INF,0))) rs+=t, ++vs, memcpy(cur+1,g+1,sizeof(int)*des);
    } return rs;
}
inline void solve() {
    n=rd(), m=rd(), src=id(n,m,2)+1; des=src+1; init(); memset(ms,0,sizeof(ms));
    for(int i=1;i<=n;i++) for(int j=1;j<m;j++) cx[i][j]=rd();
    for(int i=1;i<n;i++) for(int j=1;j<=m;j++) cy[i][j]=rd();
    for(int i=rd();i>=1;i--) {int x=rd(), y=rd(); ms[x][y]=1;}
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {
        if((i+j)&1) {
            if(j>1) add(id(i,j,1),id(i,j-1,2),1,cx[i][j-1]);
            if(j<m) add(id(i,j,1),id(i,j+1,2),1,cx[i][j]);
        } else {
            if(i>1) add(id(i,j,1),id(i-1,j,2),1,cy[i-1][j]);
            if(i<n) add(id(i,j,1),id(i+1,j,2),1,cy[i][j]);
        }
        add(src,id(i,j,1),1,0); add(id(i,j,2),des,1,0);
        if(!ms[i][j]) add(id(i,j,1),id(i,j,2),1,0);
    }
    static int tl=0; printf("Case #%d: ",++tl);
    if(maxflow()==n*m) cout<<gg<<endl;
    else cout<<"Impossible"<<endl;
}
int main() {
    for(int i=rd();i;i--) solve();
}
怎么报错应该怎么解决java.lang.IllegalArgumentException: View=com.xiaopeng.xui.widget.XLinearLayout{6842348 V.E...... ......ID 0,0-600,130} not attached to window manager 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:543) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:447) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:196) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.xiaopeng.systemui.speech.component.asr.AsrAreaWidget.onAsrHide(AsrAreaWidget.java:50) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.xiaopeng.systemui.speech.model.AsrModel.notifyChanged(AsrModel.java:85) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.xiaopeng.systemui.speech.model.AsrModel.access$100(AsrModel.java:15) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.xiaopeng.systemui.speech.model.AsrModel$1.onInputText(AsrModel.java:73) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.xiaopeng.systemui.speech.presenter.SpeechManager$2.lambda$onInputText$0$SpeechManager$2(SpeechManager.java:172) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.xiaopeng.systemui.speech.presenter.-$$Lambda$SpeechManager$2$LNEIprveqAbFGXR19BN2ru0Bj2o.run(Unknown Source:4) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:232) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.os.Looper.loop(Looper.java:334) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7985) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 05-26 17:48:27.970 10708 10708 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
05-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值