费用流求调
查看原帖
费用流求调
688674
Night_fall楼主2024/7/21 20:27

rt,调了4个小时了,有没有大佬帮帮我啊……

附代码:

#include<queue>
#include<cstring>
#include<iostream>
using namespace std;

int top[4170];
struct edge{
	int v,c,f,nxt;
}e[400010];
int ecur=1;
int anst,ans,dis[4170],topt[4170];
bool vis[400010],vist[400010];
bool anflg[400010];
int de1,de2;
bool flag;

void add(int u, int v, int c, int f){
	e[++ecur]={v,c,f,top[u]};top[u]=ecur;
	e[++ecur]={u,-c,0,top[v]};top[v]=ecur;
}

bool bfs(int s, int t){
	queue<int>q;
	q.push(s);
	memset(dis,-0x3f,sizeof(dis));
	memcpy(topt,top,sizeof(top));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	while(q.size()){
		int u=q.front();q.pop();
		for(int i=top[u];i;i=e[i].nxt){
			if(i==de1||i==de2) continue;
			int v=e[i].v,c=e[i].c;
			if(e[i].f&&dis[u]+c>dis[v]) dis[v]=dis[u]+c,q.push(v);
		}
	}
	//for(int i=1;i<=10;i++) cout<<dis[i]<<' '; cout<<'\n';
	return dis[t]>0;
}

/*
4
112 32 3 1
11 34 26 55
22 47 06 59
80 47 4 25
*/

int dfs(int x, int ret, int t){
    vis[x]=1;
	if(x==t){flag=1;return ret;}
	int lef=ret;
	for(int i=topt[x];i;i=e[i].nxt){
		if(i==de1||i==de2) continue;
		int v=e[i].v,f=e[i].f;
		topt[x]=i;
		if(dis[v]==dis[x]+e[i].c&&e[i].f&&!vis[v]){
			int tmp=dfs(v,min(f,lef),t);
			lef-=tmp;
			e[i].f-=tmp,e[i^1].f+=tmp;
			if(!tmp) dis[v]=-1e9;
		}
		if(!lef) break;
	}
	return ret-lef;
}

int main(){
	int n;
	cin>>n;
	int s=2*n+1,t=2*n+2;
	for(int i=1;i<=n;i++) add(s,i,0,1),add(i+n,t,0,1);
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) {
		int h;
		cin>>h;
		add(i,j+n,h,1);
	}
	while(bfs(s,t)) ans+=dis[t]*dfs(s,1e9,t);
	cout<<ans<<'\n';
	for(int i=2;i<=ecur;i++) if(!e[i].f&&i>4*n) vist[i]=1;
	for(int i=2;i<=ecur;i+=2){
		if(vist[i]){
			for(int j=2;j<=ecur;j+=2) e[j].f=1,e[j^1].f=0;
			de1=i,de2=i^1;anst=0;
			while(1){
			   if(!bfs(s,t)) break;
			   int tt=dfs(s,1e9,t);
			   while(flag) flag=0,anst+=dis[t]*tt,tt=dfs(s,1e9,t);
			}
			if(anst!=ans) anflg[i]=1;//cout<<i<<' ';
			//cout<<i<<' '<<anst<<'\n';
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=top[i];j;j=e[j].nxt) if(anflg[j]) cout<<i<<' '<<e[j].v-n<<'\n';
	}
	//cout<<"ED";
	return 0;
} 
2024/7/21 20:27
加载中...