MnZn socks 40分均RE 悬棺求调
查看原帖
MnZn socks 40分均RE 悬棺求调
534296
aCssen楼主2023/10/24 14:50
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define int long long 
using namespace std;
const int maxn=505;
const int maxm=200405;
int a[maxn][maxn],b[maxn][maxn],d[maxn<<1],now[maxn<<1],head[maxn<<1],ver[maxm],edge[maxm],nxt[maxm],tot,n,m,s,t;
long double dis[maxn<<1],cost[maxn<<1],l,r,ans;
bool vis[maxn<<1];
queue<int>q;
void addedge(int u,int v,int w,double c){
	ver[++tot]=v;
	edge[tot]=w;
	cost[tot]=c;
	nxt[tot]=head[u];
	head[u]=tot;
}
void add_edge(int u,int v,int w,double c){
	addedge(u,v,w,c);
	addedge(v,u,0,-c);
}
bool spfa(){
	for(int i=1;i<=2*n+2;i++){
		dis[i]=-1e18;
	}
	memset( vis, 0, sizeof(vis) ) ;
	now[s]=head[s];
	vis[s]=true;
	dis[s]=0;
	d[s]=1;
	q.push(s);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		vis[x]=false;
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i],z=edge[i];
			double w=cost[i];
			if(!z) continue;
			if(dis[x]+w>dis[y]){
				now[y]=head[y];
				dis[y]=dis[x]+w;
				d[y]=d[x]+1;
				if(!vis[y]){
					vis[y]=true;
					q.push(y);
				}
			}
		}
	}
	return dis[t]!=-1e18;
}
int dinic(int x,int flow){
	if(x==t) return flow;
	int rest=flow;
	for(int i=now[x];i&&rest;i=nxt[i]){
		now[x]=i;
		int y=ver[i],z=edge[i];
		double w=cost[i];
		if(dis[y]==dis[x]+w&&d[y]==d[x]+1&&z){
			int k=dinic(y,min(rest,z));
			if(!k) d[y]=0;
			edge[i]-=k;
			edge[i^1]+=k;
			rest-=k;
			ans+=(k*w);
		}
	}
	return flow-rest;
}
bool check(double mid){
	memset(head,0,sizeof(head));
	tot=s=1;
	t=2*n+2;
	ans=0;
	for(int i=1;i<=n;i++)
		add_edge(s,i+1,1,0);
	for(int i=1;i<=n;i++)
		add_edge(n+i+1,t,1,0);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			add_edge(i+1,j+n+1,1,a[i][j]-mid*b[i][j]);
	while(spfa()) while(dinic(s,1e9));
	return ans>0;
}
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			scanf("%lld",&a[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)	
			scanf("%lld",&b[i][j]);
	r=1e5+5;
	double eps=1e-8;
	double fuck=0;
	while(r-l>eps){
		double mid=(l+r)/2.0;
		if(check(mid))
			fuck=mid,l=mid+eps;
		else
			r=mid-eps;
	}
	printf("%0.6lf",fuck);
	return 0;
}
2023/10/24 14:50
加载中...