CFgym Son of Pipe Stream【网络流+人类智慧】

CFgym Son of Pipe Stream

可以发现Flubber可以就当成水算答案,只需要最后答案乘上 v a v^a va 即可。

记Flubber流量为 F F F ,水的流量为 W W W ,两个源点同时流的最大流为 S S S 。考虑什么样的 ( F , W ) (F,W) (F,W) 是合法的,我们可以发现一个性质:满足 F ≤ F m a x , W ≤ W m a x , F + W ≤ S F\le F{max},W\le W{max},F+W\le S FFmax,WWmax,F+WS ( W , F ) (W,F) (W,F) 都是合法的。

证明:就是固定 F F F ,跑初始流量为 F F F 源点在Flubber最大流,然后在残余网络里来跑源点在水处的最大流, W W W 一定等于 S − F S-F SF 。(呃呃呃我不知道怎么描述,所以略过证明。

然后在限制条件下, F a W 1 − a F^aW^{1-a} FaW1a 最大值在的 F W = a a − 1 \frac{F}{W}=\frac{a}{a-1} WF=a1a 处取到。

建一个超级源点 S S SS SS ,向Flubber的源点连一条流量为 F F F 的边, 向水的源点连一条流量为 W W W 的边, 把流量平衡的子图拎出来,求方案就是再以Flubber的源点为源点, F F F 为流量跑最大流,剩下的没流满的流量就是水的。

#include <bits/stdc++.h>
#define M 1000006
#define N 302
using namespace std;
typedef double db;
const double eps=1e-7,inf=1e18;
int head[N],vs,vt,tot=-1,n,m;
bool tag[M];
struct Edge {
	int data,nxt; db f; 
	Edge() {}
	Edge(int a,db b,int c):data(a),f(b),nxt(c) {}
}e[M];
void add(int x,int y,db z) {
	e[++tot]=Edge(y,z,head[x]); head[x]=tot;
	e[++tot]=Edge(x,z,head[y]); head[y]=tot;
}
namespace Flow {
	int d[N],cur[N];
	queue<int> q;
	bool bfs() {
		while(!q.empty()) q.pop();
		memset(d,-1,sizeof(d));
		d[vs]=0,cur[vs]=head[vs];
		q.push(vs); int x,y;
		while(!q.empty()) {
			x=q.front(),q.pop(); 
			for(int i=head[x];i!=-1;i=e[i].nxt)
				if(e[i].f>eps&&d[y=e[i].data]==-1) {
					d[y]=d[x]+1; cur[y]=head[y];
					if(y==vt)return 1;
					q.push(y);
				}
		}
		return 0;
	}
	db dfs(int x,db mf) {
		if(x==vt||mf<eps)return mf; //流太小就掐断 
		int y; db fl,now=0;
		for(int &i=cur[x];i!=-1;i=e[i].nxt) {
			if(e[i].f<eps||d[y=e[i].data]!=d[x]+1) continue;
			fl=dfs(y,min(mf-now,e[i].f));
			now+=fl,e[i].f-=fl,e[i^1].f+=fl;
			if(now+eps>mf)return now;
		}
		return now;
	}
	db maxflow(db maxx) {
		db res=0;
		while(bfs()&&maxx-res>eps) res+=dfs(vs,maxx-res);
		return res;
	}
}
int main(){
//	freopen("test.in","r",stdin);
	memset(head,-1,sizeof(head));
	db v,u,a,w; int x,y,z;
	scanf("%d %d %lf %lf",&n,&m,&v,&a);
	for(int i=1;i<=m;i++)
		scanf("%d %d %d",&x,&y,&z),add(x,y,z*1.0);
	db sum=0,allx=0,ally=0;
	vt=3;
	vs=1,sum=allx=Flow::maxflow(inf);
	vs=2,sum+=Flow::maxflow(inf);
	for(int i=0;i<=tot;i+=2) {
		u=(e[i].f+e[i^1].f)*0.5;
		e[i].f=e[i^1].f=u; 
	}
	ally=Flow::maxflow(inf);
	if(sum-ally>a*sum) w=sum-ally;
	else if(allx<a*sum) w=allx;
	else w=a*sum;
	for(int i=0;i<=tot;i+=2) {
		u=(e[i].f+e[i^1].f)*0.5;
		e[i].f=e[i^1].f=u; 
//	  	cout<<e[i].f<<'\n';		
	}
	vs=1,Flow::maxflow(w);
	vs=2,Flow::maxflow(sum-w);
	for(int i=0;i<=tot;i+=2) {
	  	db u=e[i].f,v=e[i^1].f;
	  	if (u<=v) {
	  		e[i].f=(v-u)*0.5;
	  		e[i^1].f=0;
//	  		cout<<e[i].f<<'\n';
		} 
		else {
			e[i^1].f=(u-v)*0.5;
			e[i].f=0;
			tag[i>>1]=1;
//			cout<<e[i^1].f<<'\n';
		}
   	}
	vs=1,Flow::maxflow(w);
	for(int i=0;i<m;i++){
//		cout<<e[2*i].f<<" "<<e[2*i+1].f<<'\n';
		if (!tag[i]) printf("%.10f %.10f\n",e[2*i+1].f/v,e[2*i].f);
    	else printf("%.10f %.10f\n",-e[2*i].f/v,-e[2*i+1].f);
	}
    	
    printf("%.10f\n",pow(w/v,a)*pow(sum-w,1.0-a));
    return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值