#6 MLE求助!!!
查看原帖
#6 MLE求助!!!
613526
LDY_楼主2024/7/12 16:49
#include<bits/stdc++.h>
#define inf 1e9
#define res 1e-8
using namespace std;
int n,s,t,num;
int head[205],cnt=1;
struct node{
	int v,nxt;
	double c,w;
}e[20005];
void adde(int u,int v,int w,double c){
	cnt++;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].c=c;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
void add(int u,int v,int w,double c){
	adde(u,v,w,c);adde(v,u,0,-c);
	//cout<<u<<" "<<v<<" "<<w<<" "<<c<<endl;
	///cout<<c<<" ";
}
int inq[205],cur[205];
double dis[205];
bool spfa(){
	queue<int> q;
	for(int i=1;i<=num;i++){
		dis[i]=-inf;
		cur[i]=head[i];
		inq[i]=0;
	}
	dis[s]=0;
	inq[s]=1;
	q.push(s);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		inq[u]=0;
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].v;
			if(dis[v]<dis[u]+e[i].c&&e[i].w){
				dis[v]=dis[u]+e[i].c;
				if(!inq[v]){
					inq[v]=1;
					q.push(v);
				}
			}
		}
	}
	return dis[t]!=-inf;
}
double maxflow,cost;
bool vis[205];
double dfs(int u,double flow){
	int rlow=0;
	if(u==t){
		vis[t]=1;
		maxflow+=flow;
		return flow;
	}
	double used=0;
	vis[u]=1;
	for(int i=cur[u];i;i=e[i].nxt){
		int v=e[i].v;
		cur[u]=i;
		if(dis[v]==dis[u]+e[i].c&&e[i].w&&(v==t||!vis[t])){
			if(rlow=dfs(v,min(flow-used,e[i].w))){
				used+=rlow;
				e[i].w-=rlow;
				e[i^1].w+=rlow;
				cost+=1.0*rlow*e[i].c;
				if(used==flow) break;
			}
		}
	}
	return used;
}
double dinic(){
	while(spfa()){
		vis[t]=1;
		while(vis[t]==1){
			memset(vis,0,sizeof(vis));
			dfs(s,inf);
		}
	}
	return maxflow;
}
double a[105][105],b[105][105];
void clean(){
	cnt=1;maxflow=0;cost=0;
	memset(head,0,sizeof(head));
	memset(e,0,sizeof(e));
	memset(dis,0,sizeof(dis));
	memset(cur,0,sizeof(cur));
	memset(inq,0,sizeof(inq));
	memset(vis,0,sizeof(vis));
}
bool p(double C){
	clean();
	for(int i=1;i<=n;i++){
		add(s,i,1,0);
		add(i+n,t,1,0);
	}
	for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
    	add(i,j+n,1,a[i][j]-C*b[i][j]);
	}
	}
	dinic();
	//cout<<":::"<<cost<<" "<<maxflow<<endl;
	return cost>=0;
}
signed main(){
	cin>>n;
	num=2*n+2;
	s=2*n+1,t=2*n+2;
	for(int i=1;i<=n;i++){
	for(int j=1;j<=n;j++){
		cin>>a[i][j];
	}
	}
	for(int i=1;i<=n;i++){
	for(int j=1;j<=n;j++){
		cin>>b[i][j];
	}
	}
	double l=0,r=1e5+5,ans=0,d=1e-9;
	
	while(r-l>res){
		double mid=(l+r)/2.0;
		if(p(mid)){
			ans=mid,l=mid+d;
			//cout<<"------"<<endl;
		}
		else{
			r=mid-d;
		
		} 
	}
	
	printf("%.6lf",ans);
	return 0;
	}
2024/7/12 16:49
加载中...