zoukankan      html  css  js  c++  java
  • 4514: [Sdoi2016]数字配对 费用流

    链接

    https://www.lydsy.com/JudgeOnline/problem.php?id=4514

    思路

    EK直接贪心做
    <0的时候加上剩余返回
    二分图a->b的时候
    把b->a也连接上
    最后除2
    整除和贪心可只知道它是对的

    代码

    #include <bits/stdc++.h>
    #define ll long long
    #define iter vector<int>::iterator
    using namespace std;
    const ll N=5e5+7;
    ll read() {
    	ll x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    ll n,S,T,a[2007],b[2007],c[2007];
    struct node {
    	ll u,v,nxt,cap,cost;
    }e[N<<1];
    ll head[N<<1],tot=1;
    void add_edge(ll u,ll v,ll cap,ll cost) {
    	e[++tot].v=v;
    	e[tot].u=u;
    	e[tot].cap=cap;
    	e[tot].cost=cost;
    	e[tot].nxt=head[u];
    	head[u]=tot;
    }
    void Add(ll u,ll v,ll cap,ll cost) {
    //	cout<<u<<" "<<v<<"
    ";
    	add_edge(u,v,cap,cost);
    	add_edge(v,u,0,-cost);
    }
    ll dis[N];
    ll vis[N],frm[N];
    bool spfa() {
    	memset(dis,-0x3f,sizeof(dis));
    	memset(vis,0,sizeof(dis));
    	queue<int> q;
    	q.push(S);
    	dis[S]=0;
    	while(!q.empty()) {
    		ll u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(ll i=head[u];i;i=e[i].nxt) {
    			ll v=e[i].v;
    			if(e[i].cap&&dis[v]<dis[u]+e[i].cost) {
    				dis[v]=dis[u]+e[i].cost;
    				frm[v]=i;
    				if(!vis[v]) {
    					vis[v]=1;
    					q.push(v);
    				}
    			}
    		}
    	}
    	return dis[T]>=-0x3f3f3f3f3f3f3f;
    }
    ll EK() {
    	ll flow=0,ans=0;
    	while(spfa()) {
    		ll now_flow=0x3f3f3f3f;
    		for(ll i=frm[T];i;i=frm[e[i].u])
    			now_flow=min(now_flow,(ll)e[i].cap);
    		for(ll i=frm[T];i;i=frm[e[i].u]) {
    			e[i].cap-=now_flow;
    			e[i^1].cap+=now_flow;
    		}
    		if(ans+1LL*now_flow*dis[T]<0) {
    			ll ok=ans/-dis[T];
    			return flow+ok;
    		} else 
    		ans+=now_flow*dis[T],flow+=now_flow;
    	}
    	return flow;
    }
    set<int> dsr[250];
    int main() {
    	freopen("a.in","r",stdin);
    	n=read();
    	for(ll i=1;i<=n;++i) a[i]=read();
    	for(ll i=1;i<=n;++i) b[i]=read();
    	for(ll i=1;i<=n;++i) c[i]=read();
    	S=1001,T=1002;
    	for(ll i=1;i<=n;++i) {
    		ll tmp=a[i];
    		for(ll j=2;j*j<=tmp;++j) {
    			if(tmp%j==0) dsr[i].insert(j);
    			while(tmp%j==0) tmp/=j;
    		}
    		if(tmp!=1) dsr[i].insert(tmp);
    	}
    	for(ll i=1;i<=n;++i) Add(S,i,b[i],0);
    	for(ll i=1;i<=n;++i) Add(i+n,T,b[i],0);
    	for(ll i=1;i<=n;++i) {
    		for(ll j=i+1;j<=n;++j) {
    			ll x=i,y=j;
    			if(a[x]<a[y]) swap(x,y);
    			if(a[y]==0) continue;
    			if(a[x]%a[y]==0) {
    				if(dsr[x].count(a[x]/a[y])) {
                       Add(x,y+n,0x3f3f3f3f3f3fLL,c[x]*c[y]);
    				   Add(y,x+n,0x3f3f3f3f3f3fLL,c[x]*c[y]);					
    				}
    			}
    		}
    	}
    	printf("%lld
    ",EK()/2LL);
    	return 0;
    }
    
  • 相关阅读:
    Advanced Sort Algorithms
    Bash Excercises
    分布式Java应用与实践 (一)
    Configure HttpClient correctly
    Automated Front End Test
    linux 判断一个用户是否存在 _fei
    linux 系统扩容 VMware Centos---VMware ESXi
    ESX 基本使用 _fei
    centos jira wiki 开机自启
    svn 添加子目录后检出失败 _fei
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10393833.html
Copyright © 2011-2022 走看看