zoukankan      html  css  js  c++  java
  • 「AGC034D」 Manhattan Max Matching

    「AGC034D」 Manhattan Max Matching

    传送门

    不知道这个结论啊。。。

    (其实就是菜嘛)

    首先 (O(n^2)) 的建边显然不太行。

    曼哈顿距离有这样一个性质,如果将绝对值符号拆掉,曼哈顿距离的值一定是所有情况的最大值。

    然后根据这个性质我们可以把点拆成四种 ((pm x,pm y)),然后连边直接跑最大流就完事了。

    /*---Author:HenryHuang---*/
    /*---Never Settle---*/
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    typedef long long ll;
    struct edge{
    	ll to,nex,w,v;
    }e[maxn*20];
    int head[maxn],cur[maxn],cnt=1;
    int n,m,s,t;
    void add(ll a,ll b,ll c,ll d){
    	e[++cnt]=(edge){b,head[a],c,d};
    	head[a]=cnt;
    }
    void addedge(ll a,ll b,ll c,ll d){
    	add(a,b,c,d),add(b,a,0,-d);
    }
    ll dis[maxn],vis[maxn];
    bool spfa(){
    	for(int i=s;i<=t;++i) dis[i]=-(1ll<<60),cur[i]=head[i];
    	queue<int> Q;
    	dis[s]=0,vis[s]=1,Q.emplace(s);
    	while(!Q.empty()){
    		ll u=Q.front();Q.pop();
    		vis[u]=0;
    		for(int i=head[u];i;i=e[i].nex){
    			int v=e[i].to;
    			if(e[i].w&&dis[v]<dis[u]+e[i].v){
    				dis[v]=dis[u]+e[i].v;
    				if(!vis[v]) vis[v]=1,Q.emplace(v);
    			}
    		}
    	}
    	return dis[t]>-(1ll<<60);
    }
    ll dfs(int u,ll in){
    	if(u==t) return in;
    	ll out=0,tmp;
    	vis[u]=1;
    	for(int i=cur[u];i;i=e[i].nex){
    		cur[u]=i;
    		int v=e[i].to;
    		if((!vis[v])&&e[i].w&&dis[v]==dis[u]+e[i].v&&(tmp=dfs(v,min(e[i].w,in)))){
    			in-=tmp,out+=tmp;
    			e[i].w-=tmp,e[i^1].w+=tmp;
    			if(!in) break;
    		}
    	}
    	if(!out) dis[u]=0;
    	vis[u]=0;
    	return out;
    }
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	cin>>n;
    	int p1=2*n+1,p2=2*n+2,p3=2*n+3,p4=2*n+4;
    	s=0,t=2*n+5;
    	for(int i=1;i<=n;++i){
    		int x,y,c;cin>>x>>y>>c;
    		addedge(s,i,c,0);
    		addedge(i,p1,c,x+y);
    		addedge(i,p2,c,x-y);
    		addedge(i,p3,c,-x+y);
    		addedge(i,p4,c,-x-y);
    	}
    	for(int i=1;i<=n;++i){
    		int x,y,c;cin>>x>>y>>c;
    		addedge(i+n,t,c,0);
    		addedge(p1,i+n,c,-x-y);
    		addedge(p2,i+n,c,-x+y);
    		addedge(p3,i+n,c,x-y);
    		addedge(p4,i+n,c,x+y);
    	}
    	ll ans=0;
    	while(spfa()){
    		ll tmp=dfs(s,1e9);
    		ans-=tmp*dis[t];
    	}
    	cout<<-ans<<'
    ';
    	return 0;
    }
    
    在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。
  • 相关阅读:
    无限极分类查找所有子孙节点的改进算法
    递归方式将数组变对象
    中文编码与解码
    MYSQL数据库
    python之进程池与线程池
    ORM介绍
    python之协程
    windows10如何将python2和python3添加到环境变量中
    互斥锁、死锁现象、递归锁、信号量
    python之GIL(Global Interpreter Lock)
  • 原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-AGC034D.html
Copyright © 2011-2022 走看看