zoukankan      html  css  js  c++  java
  • Codeforces671D Roads in Yusland

    Problem

    Codeforces

    Solution

    被神仙同学安利的一道题目,然后想了好久都没想出来= =翻翻题解发现是道神仙题


    可以把覆盖所有边的限制用矩阵的运算来描述,那么不难发现这其实是一道线性规划问题。然后这个问题不太好解决,我们可以考虑它的对偶问题。

    [max{c^Tx|Axleq b}=min{b^Ty|A^Tygeq c} ]

    正确性不会证明,只会感性地理解一下。右式的含义大概就是如果制作一个产品的成本大于等于它的收益,那么我们要最大化收益就不如把原材料直接卖了。那么这个式子的含义其实不考虑成本的最大收益等于无法获利时的最小成本,即一个临界状态,既可以做产品也可以直接卖。

    由此,问题就转化成了:要求给每条边定一个权值,使得所有链覆盖的边权和小于等于它的权值,要最大化总边权。直接从深的开始贪心即可,在每个点上处理一下它的父边的选择。

    时间复杂度 (O(mlog m))

    Code

    #include <algorithm>
    #include <cstdlib>
    #include <cstdio>
    #define pd(x) if(t[x].add)pushdown(x)
    using namespace std;
    typedef long long ll;
    const int maxn=300010;
    template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
    template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
    template <typename Tp> inline void read(Tp &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=1,ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        if(f) x=-x;
    }
    struct data{int v,nxt;}edge[maxn<<1];
    struct leftist{
    	int val,add,lc,rc,dis,del;
    }t[maxn];
    int n,m,p,tot,head[maxn],rt[maxn],dep[maxn];
    ll ans;
    void insert(int u,int v)
    {
    	edge[++p]=(data){v,head[u]};head[u]=p;
    	edge[++p]=(data){u,head[v]};head[v]=p;
    }
    int new_node(int val,int del){t[++tot].val=val;t[tot].del=del;return tot;}
    void pushdown(int x)
    {
    	int lc=t[x].lc,rc=t[x].rc;
    	if(lc){t[lc].val+=t[x].add;t[lc].add+=t[x].add;}
    	if(rc){t[rc].val+=t[x].add;t[rc].add+=t[x].add;}
    	t[x].add=0;
    }
    int merge(int x,int y)
    {
    	if(!x||!y) return x|y;
    	pd(x);pd(y);
    	if(t[x].val>t[y].val) swap(x,y);
    	t[x].rc=merge(t[x].rc,y);
    	if(t[t[x].rc].dis>t[t[x].lc].dis) swap(t[x].lc,t[x].rc);
    	t[x].dis=t[t[x].rc].dis+1;
    	return x;
    }
    void input()
    {
    	int u,v,w;
    	read(n);read(m);t[0].dis=-1;
    	for(int i=1;i<n;i++){read(u);read(v);insert(u,v);}
    	for(int i=1;i<=m;i++)
    	{
    		read(u);read(v);read(w);
    		rt[u]=merge(rt[u],new_node(w,v));
    	}
    }
    void dfs(int x,int pre)
    {
    	dep[x]=dep[pre]+1;
    	for(int i=head[x];i;i=edge[i].nxt)
    	  if(edge[i].v^pre)
    	  {
    	  	dfs(edge[i].v,x);
    	  	rt[x]=merge(rt[x],rt[edge[i].v]);
    	  }
    	if(x==1) return ;
    	while(rt[x]&&dep[t[rt[x]].del]>=dep[x]) rt[x]=merge(t[rt[x]].lc,t[rt[x]].rc);
    	if(!rt[x]){puts("-1");exit(0);}
    	int tmp=t[rt[x]].val;
    	t[rt[x]].val-=tmp;t[rt[x]].add-=tmp;
    	ans+=tmp;
    }
    int main()
    {
    	input();
    	dfs(1,1);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    tp5 window环境迁移到一键lnmp流程问题笔记
    构建:什么是构建
    requests--etree--xpath
    python-requests
    python正则表达式03--字符串中匹配数字
    python正则表达式02--findall()和search()方法区别,group()方法
    python正则表达式01--贪心算法和非贪心算法findall()
    UIViewController的生命周期(根视图view从无到有的过程)
    CoreData基础
    XMPP即时通信(基础)
  • 原文地址:https://www.cnblogs.com/totorato/p/10597086.html
Copyright © 2011-2022 走看看