zoukankan      html  css  js  c++  java
  • 【JZOJ6346】ZYB和售货机

    description


    analysis

    • 其实这个连出来的东西叫基环内向树

    • 先考虑很多森林的情况,也就是树根连回自己

    • 明显树根物品是可以被取完的,那么买树根的价钱要是儿子中价钱最小的那个

    • 或者把那个叫成收益,也就是选择所有儿子中收益最大的儿子

    • 既然树根可以取完,同理所有非叶子节点也可以被取完

    • 所以树(森林)的情况就可以(O(n))遍历一遍得到

    • 考虑在基环树上删去一条边,使得图变成树,然后用树的做法

    • 如果购买一个点的父亲(x),卖钱比另一个父亲也为(x)的要差,那就不用按按钮

    • 没有这种情况,就钦定环上环边贡献减去树边贡献最小的点断开环边

    • 记录每个点的儿子中收益最大和次大的儿子,就可以知道两个贡献之差


    code

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXN 100005
    #define MAXM MAXN*2
    #define ha 19260817
    #define ll long long
    #define reg register ll
    #define fo(i,a,b) for (reg i=a;i<=b;++i)
    #define fd(i,a,b) for (reg i=a;i>=b;--i)
    #define rep(i,a) for (reg i=last[a];i;i=next[i])
    
    using namespace std;
    
    ll last[MAXM],next[MAXM],tov[MAXM];
    ll fa[MAXN],a[MAXN],c[MAXN],d[MAXN];
    ll dfn[MAXN],num[MAXN],val[MAXN],mx[MAXN],smx[MAXN];
    ll bz[MAXN],flag[MAXN];
    ll n,mn=ha,tot,ans,where;
    
    inline ll read()
    {
    	ll x=0,f=1;char ch=getchar();
    	while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
    	while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    inline ll max(ll x,ll y){return x>y?x:y;}
    inline ll min(ll x,ll y){return x<y?x:y;}
    inline void link(ll x,ll y){next[++tot]=last[x],last[x]=tot,tov[tot]=y;}
    /*
    inline void findcircle(ll x)
    {
    	if (dfn[x]==tot)
    	{
    		fo(i,1,n)if (dfn[x]==tot)bz[i]=1;
    		return;
    	}
    	if (dfn[x])return;
    	dfn[x]=tot;if (x!=fa[x])findcircle(fa[x]);
    }
    inline void dfs(ll x)
    {
    	ans+=val[mx[x]]*a[x];
    	rep(i,x)dfs(tov[i]);
    }*/
    
    inline void dfs1(ll x)
    {
    	if (flag[x]==tot){ans-=mn;return;}
    	if (flag[x])return;
    	flag[x]=tot,mn=min(mn,val[mx[x]]-val[smx[x]]);
    	if (mx[x]!=x)dfs1(mx[x]);
    }
    
    int main()
    {
    	//freopen("T2.in","r",stdin);
    	freopen("goods.in","r",stdin);
    	freopen("goods.out","w",stdout);
    	n=read();
    	fo(i,1,n)fa[i]=read(),c[i]=read(),d[i]=read(),a[i]=read(),link(fa[i],i);
    	fo(i,1,n)
    	{
    		val[i]=d[fa[i]]-c[i];
    		if (val[i]<0)continue;
    		if (val[i]>val[mx[fa[i]]])smx[fa[i]]=mx[fa[i]],mx[fa[i]]=i;
    		else if (val[i]>val[smx[fa[i]]])smx[fa[i]]=i;
    	}
    	tot=0;
    	//fo(i,1,n)if (!dfn[i])++tot,findcircle(i);
    	fo(i,1,n)ans+=val[mx[i]]*a[i];
    	tot=0;
    	fo(i,1,n)if (!flag[i])++tot,mn=ha,dfs1(i);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    mybatis mybatis-generator 代码自动生成工具使用
    spring初步
    spring基于xml和注解配置事务
    强软弱虚四大引用
    线程通信的几种实现方式
    java8新特性之方法引用和构造器引用
    JAVA四大内置函数
    JAVA四大内置函数
    JSR303的使用
    设计模式之建造者模式
  • 原文地址:https://www.cnblogs.com/horizonwd/p/11498461.html
Copyright © 2011-2022 走看看