• BZOJ4514[Sdoi2016]数字配对——最大费用最大流


    题目描述

    有 n 种数字,第 i 种数字是 ai、有 bi 个,权值是 ci。
    若两个数字 ai、aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数,
    那么这两个数字可以配对,并获得 ci×cj 的价值。
    一个数字只能参与一次配对,可以不参与配对。
    在获得的价值总和不小于 0 的前提下,求最多进行多少次配对。

    输入

    第一行一个整数 n。
    第二行 n 个整数 a1、a2、……、an。
    第三行 n 个整数 b1、b2、……、bn。
    第四行 n 个整数 c1、c2、……、cn。

    输出

     一行一个数,最多进行多少次配对

    样例输入

    3
    2 4 8
    2 200 7
    -1 -2 1

    样例输出

    4

    提示

     n≤200,ai≤10^9,bi≤10^5,∣ci∣≤10^5

    有数量上限、有价值,显然费用流,因为题目要求费用不小于$0$,所以用最大费用最大流。将每个点拆成两个点$i$和$i'$,分别与源点和汇点连边,流量为$b[i]$、费用为$0$。枚举任意两个数判断是否能匹配。因为$i$与$j$能匹配,$j$就能与$i$匹配,所以将$i$与$j'$连边、$j$与$i'$连边,流量为$INF$、费用为$-c[i]*c[j]$(因为跑最大费用最大流,边权取反)。每次$SPFA$找到一条增广路,如果加上之后答案满足要求就继续增广,否则就停止。因为一对数的匹配算了两次,所以最后答案除$2$即可。

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<bitset>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    #define INF 1000000000000000ll
    #define inf 1000000000
    using namespace std;
    int head[1000];
    int next[100000];
    int to[100000];
    ll v[100000];
    int c[100000];
    int f[1000];
    int from[100000];
    int tot=1;
    int S,T;
    ll ans;
    int n;
    int A[300];
    int B[300];
    int C[300];
    queue<int>q;
    int vis[1000];
    ll d[1000];
    int maxflow;
    void add(int x,int y,ll z,int w)
    {
    	next[++tot]=head[x];
    	head[x]=tot;
    	to[tot]=y;
    	v[tot]=z;
    	c[tot]=w;
    	from[tot]=x;
    	next[++tot]=head[y];
    	head[y]=tot;
    	to[tot]=x;
    	v[tot]=-z;
    	c[tot]=0;
    	from[tot]=y;
    }
    bool result()
    {
    	int now=T;
    	int flow=inf;
    	while(now!=S)
    	{
    		flow=min(flow,c[f[now]]);
    		now=from[f[now]];
    	}
    	if(ans+d[T]*flow<=0)
    	{
    		ans+=d[T]*flow;
    		maxflow+=flow;
    	}
    	else
    	{
    		maxflow+=fabs(ans)/fabs(d[T]);
    		return 1;
    	}
    	now=T;
    	while(now!=S)
    	{
    		c[f[now]]-=flow;
    		c[f[now]^1]+=flow;
    		now=from[f[now]];
    	}
    	return 0;
    }
    bool SPFA()
    {
        for(int i=1;i<=T;i++)
        {
            d[i]=INF;
        }
        d[S]=0;
        q.push(S);
        vis[S]=1;
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            vis[now]=0;
            for(int i=head[now];i;i=next[i])
            {
                if(!c[i])
                {
                    continue;
                }
                if(d[to[i]]>d[now]+v[i])
                {
                    d[to[i]]=d[now]+v[i];
                    f[to[i]]=i;
                    if(!vis[to[i]])
                    {
                        q.push(to[i]);
                        vis[to[i]]=1;
                    }
                }
            }
        }
        return d[T]!=INF;
    }
    void find_max()
    {
    	while(SPFA())
    	{
    		if(result())
    		{
    			break;
    		}
    	}
    }
    bool check(int x,int y)
    {
    	if(x<y)
    	{
    		swap(x,y);
    	}
    	if(x%y)
    	{
    		return false;
    	}
    	int d=x/y;
    	for(int i=2;i*i<=d;i++)
    	{
    		if(d%i==0)
    		{
    			return false;
    		}
    	}
    	return true;
    }
    int main()
    {
    	scanf("%d",&n);
    	S=2*n+1,T=S+1;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&A[i]);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&B[i]);
    		add(S,i,0,B[i]);
    		add(i+n,T,0,B[i]);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&C[i]);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=i+1;j<=n;j++)
    		{
    			if(check(A[i],A[j]))
    			{
    				add(i,n+j,-1ll*C[i]*C[j],1<<30);
    				add(j,n+i,-1ll*C[i]*C[j],1<<30);
    			}
    		}
    	}
    	find_max();
    	printf("%d",maxflow/2);
    }
  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/10569763.html
Copyright © 2020-2023  润新知