zoukankan      html  css  js  c++  java
  • SDOI2017新生舞会

    (n100)

    简单的分数规划+费用流

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f==1?x:-x;
    }
    const double inf=1e8,eps=1e-10;
    const int N=104;
    struct edge{
    	int v,nxt,f;
    	double c;
    }e[N*N*2];
    int first[N<<1],cur[N<<1],cnt,vis[N<<1],s,t;
    double dis[N<<1],mon;
    inline void clear(){
    	memset(first,0,sizeof(first));
    	cnt=1;mon=0;
    }
    inline void ADD(int u,int v,double c,int f){
    	e[++cnt].v=v;e[cnt].c=c;e[cnt].f=f;
    	e[cnt].nxt=first[u];first[u]=cnt;
    }
    inline void add(int u,int v,double c,int f){
    	ADD(u,v,c,f);
    	ADD(v,u,-c,0);
    }
    inline bool spfa(){
    	static queue<int>q;
    	for(int i=1;i<=t;i++)dis[i]=inf;
    	memset(vis,0,(t+1)<<2);
    	dis[t]=0;vis[t]=1;
    	q.push(t);
    	while(!q.empty()){
    		int x=q.front();q.pop();
    		vis[x]=0;
    		for(int i=first[x],v;i;i=e[i].nxt){
    			if(!e[i^1].f)continue;
    			v=e[i].v;
    			if(dis[v]>dis[x]-e[i].c){
    				dis[v]=dis[x]-e[i].c;
    				if(!vis[v]){q.push(v);vis[v]=1;}
    			}
    		}
    	}
    	return fabs(dis[s]-inf)>eps;
    }
    int dfs(int x,int f){
    	if(!f)return 0;
    	if(x==t){vis[0]=1;return f;}
    	vis[x]=1;
    	int used=0;
    	for(int &i=cur[x],v,w;i;i=e[i].nxt){
    		v=e[i].v;
    		if(vis[v]||fabs(dis[x]-dis[v]-e[i].c)>eps||!e[i].f)continue;
    		w=dfs(v,min(f,e[i].f));
    		if(!w)continue;
    		e[i].f-=w;e[i^1].f+=w;
    		used+=w;f-=w;
    		mon+=e[i].c*w;
    		if(!f)break;
    	}
    	return used;
    }
    inline void mcmf(){
    	while(spfa()){
    		memcpy(cur,first,(t+1)<<2);
    		vis[0]=1;
    		while(vis[0]){
    			memset(vis,0,(t+1)<<2);
    			dfs(s,inf);
    		}
    	}
    }
    int n,a[N][N],b[N][N];
    int main(){
    	n=read();s=(n<<1)+1;t=s+1;
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			a[i][j]=read();
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			b[i][j]=read();
    	double l=0,r=10000,mid;
    	for(int i=1;i<=50;i++){
    		mid=(l+r)/2;
    		clear();
    		for(int j=1;j<=n;j++){
    			add(s,j,0,1);
    			add(j+n,t,0,1);
    		}
    		for(int u=1;u<=n;u++)
    			for(int v=1;v<=n;v++){
    				add(u,v+n,mid*b[u][v]-a[u][v],1);
    			}
    		mcmf();
    		if(mon<=0)l=mid;
    		else r=mid;
    	}
    	printf("%.6lf",r);
    	return (0-0);
    }
    
  • 相关阅读:
    常用排序算法
    多线程基础知识 转
    转 大型项目架构演进过程
    TCP/IP 思维导图
    Java8 List字符串 去重
    docker lnmp php
    jpa 批量插入
    备忘提醒
    IntelliJ IDEA像Eclipse一样打开多个项目(转)
    IntelliJ Idea 常用快捷键列表
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12509869.html
Copyright © 2011-2022 走看看