zoukankan      html  css  js  c++  java
  • 【[SCOI2013]摩托车交易 】

    倍增什么的最慢了,常数太大了

    我们可以上树剖啊

    但是如果用树剖来查询树上两点之间的最小边权的话,可能只能在上一棵线段树?

    那也太(naive)了,尽管倍增常数大,但是还是比两个(log)快的

    那干脆重构树算了

    我们直接建出(kruskal)重构树,之后我们可以在重构树上直接用树剖来查询(lca)(lca)的点权就是最小边的边权

    这就是我最优解的原因了

    之后发现自己的思路非常清奇,那就干脆再写一下思路吧

    可能是我太傻了,并没有发现可以直接贪心,所以搞出来一种非常难写的方法

    我们定义一个(Maxn)数组,(Maxn[i])表示(i)次交易后最多可以携带多少枚金子

    显然(Maxn[n]=0)(n)次交易后我们不能再有金子了

    之后我们倒着推出(Maxn)数组

    首先(Maxn[i])应该等于(i)次交易和(i+1)次交易之间两点的最小边权

    如果(a[i+1]<0),我们可以通过卖出消耗掉一些,那就说明我们可以多往后传递一些,于是就有(Maxn[i]-|a[i+1]|<=Maxn[i+1])

    也就是(Maxn[i]<=Maxn[i]-a[i+1])

    如果(a[i+1]>0),我们卖出都不能了,于是就有(Maxn[i]<=Maxn[i+1])

    求出(Maxn)数组之后贪心就可以啦

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #define re register
    #define maxn 100005
    #define INF 9999999999
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    struct E
    {
    	int v,nxt;
    }e[maxn<<2];
    struct g
    {
    	int x,y;
    	LL z;
    }G[maxn<<1];
    int fa[maxn<<1];
    int sum[maxn<<1],Fa[maxn<<1],top[maxn<<1],deep[maxn<<1],son[maxn<<1],head[maxn<<1];
    int n,m,q,num;
    LL Maxn[maxn];
    int c[maxn<<1];
    LL a[maxn],b[maxn];
    LL val[maxn<<2];
    inline LL read()
    {
    	char c=getchar();
    	LL x=0,r=1;
    	while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
    	while(c>='0'&&c<='9')
    		x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x*r;
    }
    inline int find(int x)
    {
    	if(x==fa[x]) return x;
    	return fa[x]=find(fa[x]);
    }
    inline void add_edge(int x,int y)
    {
    	e[++num].v=y;
    	e[num].nxt=head[x];
    	head[x]=num;
    }
    void dfs1(int x)
    {
    	sum[x]=1;
    	int maxx=-1;
    	for(re int i=head[x];i;i=e[i].nxt)
    	if(!deep[e[i].v])
    	{
    		deep[e[i].v]=deep[x]+1;
    		Fa[e[i].v]=x;
    		dfs1(e[i].v);
    		sum[x]+=sum[e[i].v];
    		if(sum[e[i].v]>maxx) maxx=sum[e[i].v],son[x]=e[i].v;
    	}
    }
    void dfs2(int x,int topf)
    {
    	top[x]=topf;
    	if(!son[x]) return;
    	dfs2(son[x],topf);
    	for(re int i=head[x];i;i=e[i].nxt)
    	if(deep[e[i].v]>deep[x]&&son[x]!=e[i].v) dfs2(e[i].v,e[i].v);
    }
    inline int LCA(int x,int y)
    {
    	while(top[x]!=top[y])
    	{
    		if(deep[top[x]]<deep[top[y]]) std::swap(x,y);
    		x=Fa[top[x]];
    	}
    	if(deep[x]<deep[y]) return x;
    	return y;
    }
    inline int cmp(g a,g b)
    {
    	return a.z>b.z;
    }
    signed main()
    {
    	n=read(),m=read(),q=read();
    	for(re int i=1;i<=n;i++) b[i]=read();
    	for(re int i=1;i<=n;i++) a[i]=read();
    	for(re int i=1;i<=m;i++)
    		G[i].x=read(),G[i].y=read(),G[i].z=read();
    	for(re int i=1;i<=n*2;i++) c[i]=i;
    	if(q>=1)
    	{
    		int pre=read(),X;
    		for(re int i=1;i<q;i++)
    		{
    			X=read();
    			c[X]=pre;
    		}
    	}
    	std::sort(G+1,G+m+1,cmp);
    	for(re int i=1;i<=n*2;i++)
    	if(c[i]==i) fa[i]=i;
    	int cnt=n;
    	for(re int i=1;i<=m;i++)
    	{
    		int xx=find(c[G[i].x]);
    		int yy=find(c[G[i].y]);
    		if(xx==yy) continue;
    		add_edge(++cnt,xx),add_edge(cnt,yy);
    		add_edge(xx,cnt),add_edge(yy,cnt);
    		val[cnt]=G[i].z;
    		fa[xx]=cnt,fa[yy]=cnt;
    	}
    	deep[cnt]=1;
    	dfs1(cnt);
    	dfs2(cnt,cnt);
    	Maxn[n]=0;
    	for(re int i=n-1;i;i--)
    	{
    		int lca=LCA(c[b[i]],c[b[i+1]]);
    		Maxn[i]=val[lca];
    		if(lca==c[b[i]]) Maxn[i]=INF;
    		if(a[b[i+1]]<0)
    			Maxn[i]=min(Maxn[i+1]-a[b[i+1]],Maxn[i]);
    		else
    			Maxn[i]=min(Maxn[i],Maxn[i+1]);
    	}
    	LL now=0;
    	for(re int i=1;i<=n;i++)
    	{
    		if(a[b[i]]>0) now=min(Maxn[i],a[b[i]]+now);
    		else 
    		{
    			printf("%lld
    ",min(now,-a[b[i]]));
    			now+=a[b[i]];
    			now=max(now,0);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    浮动清除
    解剖JavaScript中的null和undefined【转】
    关于innerHTML以及html2dom
    javascript 作用域
    4390. 【GDOI2016模拟3.16】图计数 (Standard IO)
    5049. 【GDOI2017模拟一试4.11】腐女的生日
    4273_NOIP2015模拟10.28B组_圣章-精灵使的魔法语
    jzoj_5631_(NOI2018模拟4.5)_A
    jzoj_1001_最难的问题_Floyd
    jzoj_3385_黑魔法师之门
  • 原文地址:https://www.cnblogs.com/asuldb/p/10206140.html
Copyright © 2011-2022 走看看