社区讨论

蒟蒻求助

P4014分配问题参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mi7rodly
此快照首次捕获于
2025/11/21 02:30
4 个月前
此快照最后确认于
2025/11/21 02:30
4 个月前
查看原帖
CPP
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define INF 0x3f3f3f
#define int long long
using namespace std;
const int MAX=10000;
int read(){
    int a=0,w=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()){
      if(ch == '-') w=-1;
    }
    for(;isdigit(ch);ch=getchar()){
      a=(a<<3)+(a<<1)+(ch^48);
    }
    return a*w;
}
struct edge{
    int to,nex,dis,flow;
}e[800100];
int head[MAX];
int cnt=1;
int ans;
inline void add_edge(int u,int v,int w,int cost){
      e[++cnt].to=v;e[cnt].nex=head[u];head[u]=cnt;e[cnt].flow=w;e[cnt].dis=cost;
      e[++cnt].to=u;e[cnt].nex=head[v];head[v]=cnt;e[cnt].flow=0;e[cnt].dis=-cost;
}

int s,t;
int vis[MAX],dis[MAX],pre[800100],incf[800100];
bool spfa(int k){
    for(int i=0;i<=t;++i) dis[i]=k*INF;
    queue<int> q;
    q.push(s);vis[s]=1;dis[s]=0;
    incf[s]=0x3f3f3f;
     while(!q.empty()){
       int u=q.front();q.pop();
       vis[u]=0;
       //cout<<u<<" ";
       for(int i=head[u];i;i=e[i].nex){
       		int v=e[i].to;
       		//cout<<v;
       		if(dis[v]*k > k*(dis[u]+e[i].dis) && e[i].flow != 0){
       		      dis[v] = e[i].dis+dis[u];
       		      incf[v]=min(incf[u],e[i].flow);
       		      pre[v]=i;
       		     // cout<<"oo";
       		      if(!vis[v]){q.push(v);vis[v]=1;}
       		}
       }
    }
    //cout<<dis[t];
    return dis[t] != k*INF;
}

void updete(){
    int x=t;
    //cout<<111;
    while(x!=s){
       int i=pre[x];
       e[i].flow-=incf[x];
       e[i+1].flow+=incf[x];
       x=e[i+1].to;
    }
    //cout<<dis[t]*incf[t];
    ans+=dis[t]*incf[t];
}

inline void EK(int k){
        while(spfa(k)){
            updete();
        }
}

signed main(){
    int n;
    n=read();
    s=2*n+2,t=2*n+3;
    for(int i=1;i<=n;++i){add_edge(s,i,1,0);add_edge(i+n,t,1,0);}
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            int xx;
            xx=read();
            add_edge(i,j+n,1,xx);		    
        }
    }
    EK(1);cout<<ans<<endl;
    ans=0;
    for(int i=2;i<=cnt;i+=2) {e[i].flow+=e[i+1].flow;e[i+1].flow=0;}
    EK(-1);cout<<ans;	 
}

回复

3 条回复,欢迎继续交流。

正在加载回复...