zoukankan      html  css  js  c++  java
  • bzoj 4514: 数字配对

    题目大意

    自己看

    题解

    我们打表观察规律发现一定能构成一张二分图
    也就是不存在奇环
    所以我们一般保证费用非负的最大流即可.

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    template<typename T>inline void read(T &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 256;
    const int inf = 0x3f3f3f3f;
    inline bool judge(int n){
    	if(n == 1) return false;
    	if(n == 2) return true;
    	for(int i = 2;i*i<=n;++i){
    		if(n % i == 0) return false;
    	}return true;
    }
    int a[maxn],b[maxn];ll c[maxn];
    namespace gra{
    	struct Edge{
    		int to,next;
    	}G[21010];
    	int head[maxn],cnt;
    	void add(int u,int v){
    		//printf("%d
    ",cnt);
    		G[++cnt].to = v;
    		G[cnt].next = head[u];
    		head[u] = cnt;
    	}
    	inline void insert(int u,int v){
    		add(u,v);add(v,u);
    	}
    	int col[maxn];
    #define v G[i].to
    	void dfs(int u,int c){
    		col[u] = c;
    		for(int i = head[u];i;i=G[i].next){
    			if(col[v] == -1) dfs(v,c^1);
    		}
    	}
    #undef v
    }
    namespace net{
    	struct Edge{
    		int to,next,cap;
    		ll cost;
    	}G[21010];
    	int head[maxn],cnt=1;
    	void add(int u,int v,int c,ll co){
    		//printf("%d
    ",cnt);
    		G[++cnt].to = v;
    		G[cnt].next = head[u];
    		head[u] = cnt;
    		G[cnt].cap = c;
    		G[cnt].cost = co;
    	}
    	inline void insert(int u,int v,int c,ll co){
    		//printf("%d -> %d (%d,%lld)
    ",u,v,c,co);
    		add(u,v,c,co);add(v,u,0,-co);
    	}
    	const int lim = maxn<<2;
    	int S = maxn-5,T = S+1,l,r,q[lim+10];
    	int flow[maxn],p[maxn];
    	ll dis[maxn],nw_dis;
    	int ans;
    	bool inq[maxn];
    	inline int find(int r,ll w){
    		int l = 0,ret = 0;
    		while(l <= r){
    			int mid = l+r >> 1;
    			if(mid*w+nw_dis >= 0) ret = mid,l = mid+1;
    			else r = mid-1;
    		}return ret;
    	}
    #define v G[i].to
    	bool spfa(){
    		memset(dis,-0x3f,sizeof dis);
    		l = 0;r = -1;q[++r] = S;
    		dis[S] = 0;flow[S] = inf;
    		inq[S] = true;
    		while(l <= r){
    			int u = q[l % lim];++l;
    			for(int i = head[u];i;i=G[i].next){
    				if(dis[v] < dis[u] + G[i].cost && G[i].cap){
    					dis[v] = dis[u] + G[i].cost;
    					flow[v] = min(flow[u],G[i].cap);
    					p[v] = i;
    					if(!inq[v]){
    						q[++r % lim] = v;
    						inq[v] = true;
    					}
    				}
    			}inq[u] = false;
    		}if(dis[T] == dis[0]) return false;
    		if(dis[T] < 0) flow[T] = find(flow[T],dis[T]);
    		if(flow[T] == 0) return false;
    		ans += flow[T];
    		nw_dis += flow[T]*dis[T];
    		for(int u = T;u != S;u = G[p[u]^1].to)
    			G[p[u]].cap -= flow[T],G[p[u]^1].cap += flow[T];
    		return true;
    	}
    #undef v
    }
    int main(){
    	int n;read(n);memset(gra::col,-1,sizeof gra::col);
    	for(int i=1;i<=n;++i) read(a[i]);
    	for(int i=1;i<=n;++i) read(b[i]);
    	for(int i=1;i<=n;++i) read(c[i]);
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			if(i == j) continue;
    			if(a[i] % a[j] == 0 && judge(a[i]/a[j])){
    				gra::insert(i,j);
    			}
    		}
    	}
    	for(int i=1;i<=n;++i) if(gra::col[i] == -1) gra::dfs(i,0);
    	for(int u=1;u<=n;++u){
    		if(gra::col[u] == 0){
    			net::insert(net::S,u,b[u],0);
    			for(int i = gra::head[u];i;i=gra::G[i].next){
    				net::insert(u,gra::G[i].to,inf,c[u]*c[gra::G[i].to]);
    			}
    		}else{
    			net::insert(u,net::T,b[u],0);
    		}
    	}while(net::spfa());
    	printf("%d
    ",net::ans);
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    Pandas对于CSV的简单操作
    前端之BOM和DOM
    前端之JavaScript
    前端之CSS初识
    定时ping取返回值并绘图
    etree不存在解决方法
    内置方法练习(一)
    pip使用
    python变量、变量属性
    python 爬取段子网段子写入文件
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6410992.html
Copyright © 2011-2022 走看看