联考20200523 T3 秘密行动





分析:
真是又臭又长的题面,读半天才读懂。。。
本质是一个数包含一个质因数与否对应一个代价,两个数包含某质因数状态不同对应一个代价
把10个质因数对应进n个数,拆分成10n个独立的元素,建立网络流模型
每个元素归属某个集合有一个代价,某两个元素归属不同集合也有一个代价
经典的最小割模型
可问题是求积最小,最小割是和最小
将代价取对数,积最小就变成和最小了(划重点)
跑最小割就好了,答案求幂输出就好了,卡卡精度

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<queue>
#include<algorithm>

#define maxn 2005
#define maxm 50005
#define INF 0x3f3f3f3f
#define eps 1e-8

using namespace std;

inline int getint()
{
	int num=0,flag=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
	return num*flag;
}

int n,m,S,T;
int fir[maxn],tp[maxn],nxt[maxm],to[maxm],cnt;
long double cap[maxm],Fs[maxn];
long double ans;
int h[maxn];

inline void newnode(int u,int v,long double w)
{to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;}
inline void insert(int u,int v,long double w)
{newnode(u,v,w),newnode(v,u,0);}

inline bool bfs()
{
	memset(h,-1,sizeof h);
	queue<int>Q;h[S]=0,Q.push(S);
	while(!Q.empty())
	{
		int u=Q.front();Q.pop();
		for(int i=fir[u];i;i=nxt[i])
			if(cap[i]>eps&&!~h[to[i]])h[to[i]]=h[u]+1,Q.push(to[i]);
	}
	return ~h[T];
}

inline long double dfs(int u,long double flow)
{
	if(u==T)return flow;
	long double used=0;
	for(int &i=tp[u];i;i=nxt[i])
		if(cap[i]>eps&&h[to[i]]==h[u]+1)
		{
			long double w=flow-used;
			w=dfs(to[i],min(cap[i],w));
			cap[i]-=w,cap[i^1]+=w,used+=w;
			if(flow-used<eps)return flow;
		}
	if(used<eps)h[u]=-1;
	return used;
}

inline void dinic()
{while(bfs())memcpy(tp,fir,sizeof fir),ans+=dfs(S,INF);}

int main()
{
	n=getint(),m=getint();S=10*n+1,T=S+1;cnt=1;
	for(int i=1;i<=10;i++)
	{
		getint(),cin>>Fs[i];
		Fs[i]=log(Fs[i]);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=10;j++)
		{
			long double x;cin>>x;
			insert(S,i*10+j-10,log(x));
		}
		for(int j=1;j<=10;j++)
		{
			long double x;cin>>x;
			insert(i*10+j-10,T,log(x));
		}
	}
	for(int i=1;i<=m;i++)
	{
		int u=getint(),v=getint(),w=getint();
		insert(u*10+w-10,v*10+w-10,Fs[w]),insert(v*10+w-10,u*10+w-10,Fs[w]);
	}
	dinic();
	printf("%.8lf\n",double(exp(ans)));
}

posted @ 2020-05-25 16:18  Izayoi_Doyo  阅读(146)  评论(0编辑  收藏  举报