题目:http://ch.ezoj.tk/contest/CH%20Round%20%2340%20-%20Fimbulvetr%3A%3APrologue/起源

题意:树上最大流+费用流,源点为树根,汇点为叶节点。

题解:

最大流貌似很好求?

这样搞

void dp(int x)
{
f[x]=;
for(int i=head[x],y;i;i=e[i].next)
{
y=e[i].go;
dp(y);
f[x]+=min(e[i].v,f[y]);
}
if(!head[x])f[x]=inf;
}

然后 f[root]就是答案。

然后最小费用怎么搞呢?因为汇点是叶节点,所以一个叶节点到根的费用代表着一次增广,那我们如何分配流量,使得费用最小呢?

贪心!把每个叶节点的费用算出来,然后排序,从小的开始选,流量为它到根的流量的min,然后这条路上的流量都减去min,更新ans,

取min和修改 树剖即可,对LCT还不熟悉,不敢写。

然后继续选择后面的节点,直到流量分配完毕。

考场上由于一个return 少写了,然后1h写出来但没有调出来,感觉十分桑心,不过考后交了1A也算是对我的一种补偿。

代码:

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 100000+10000
#define maxm 500+100
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
struct edge{int go,next,v,c;}e[*maxn];
struct seg{int l,r,tag,mi;}t[*maxn];
struct rec{int x,y;}a[maxn];
int n,tot,root,cnt=,top[maxn],b[maxn],p[maxn],v[maxn];
int fa[maxn],dep[maxn],head[maxn],son[maxn],s[maxn],f[maxn],inp[maxn];
int ret,ans,sum;
void insert(int x,int y,int v,int c)
{
e[++tot].go=y;e[tot].next=head[x];e[tot].v=v;e[tot].c=c;head[x]=tot;
}
void dp(int x)
{
f[x]=;
for(int i=head[x],y;i;i=e[i].next)
{
y=e[i].go;
dp(y);
f[x]+=min(e[i].v,f[y]);
}
if(!head[x])f[x]=inf;
}
void dfs(int x,int z)
{
s[x]=;
for(int y=son[x]=,i=head[x];i;i=e[i].next)
{
fa[y=e[i].go]=x;dfs(y,z+e[i].c);
b[y]=e[i].v;
s[x]+=s[y];if(s[y]>s[son[x]])son[x]=y;
}
if(!head[x]){a[++sum].x=z;a[sum].y=x;}
}
void dfs2(int x,int chain)
{
p[x]=++cnt;top[x]=chain;
if(son[x])dfs2(son[x],chain);
for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
if(y!=son[x])dfs2(y,y);
}
void pushup(int k)
{
t[k].mi=min(t[k<<].mi,t[k<<|].mi);
}
void update(int k,int z)
{
t[k].tag+=z;
t[k].mi-=z;
}
void pushdown(int k)
{
if(!t[k].tag)return;
update(k<<,t[k].tag);
update(k<<|,t[k].tag);
t[k].tag=;
}
void build(int k,int l,int r)
{
t[k].l=l;t[k].r=r;t[k].tag=;
if(l==r){t[k].mi=v[l];return;};
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
pushup(k);
}
void change(int k,int x,int y,int z)
{
int l=t[k].l,r=t[k].r,mid=(l+r)>>;
if(l==x&&r==y){update(k,z);return;}
pushdown(k);
if(y<=mid)change(k<<,x,y,z);
else if(x>mid)change(k<<|,x,y,z);
else change(k<<,x,mid,z),change(k<<|,mid+,y,z);
pushup(k);
}
int query(int k,int x,int y)
{
int l=t[k].l,r=t[k].r,mid=(l+r)>>;
if(l==x&&r==y)return t[k].mi;
pushdown(k);
if(y<=mid)return query(k<<,x,y);
else if(x>mid)return query(k<<|,x,y);
else return min(query(k<<,x,mid),query(k<<|,mid+,y));
}
int getmin(int x)
{
int tt=inf;
while(top[x]!=root)
{
tt=min(tt,query(,p[top[x]],p[x]));
x=fa[top[x]];
}
tt=min(tt,query(,,p[x]));
return tt;
}
void solvechange(int x,int y)
{
while(top[x]!=root)
{
change(,p[top[x]],p[x],y);
x=fa[top[x]];
}
change(,,p[x],y);
}
inline bool cmp(rec a,rec b)
{
return a.x<b.x;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();
for1(i,n-)
{
int x=read(),y=read(),v=read(),c=read();
insert(x,y,v,c);
inp[y]++;
}
for1(i,n)if(!inp[i])root=i;
dp(root);
dfs(root,);
dfs2(root,root);
sort(a+,a+sum+,cmp);
for1(i,n)v[p[i]]=b[i];
v[]=inf;
build(,,n);
ans=f[];printf("%d\n",ans);
ret=;
for1(i,sum)
{
int tmp=min(ans,getmin(a[i].y));
ret+=tmp*a[i].x;
solvechange(a[i].y,tmp);
ans-=tmp;
if(ans==)break;
}
printf("%d\n",ret);
return ;
}

CH Round #40 - Fimbulvetr::Prologue的更多相关文章

  1. Educational Codeforces Round 40 C. Matrix Walk( 思维)

    Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memor ...

  2. CH Round #52 还教室[线段树 方差]

    还教室 CH Round #52 - Thinking Bear #1 (NOIP模拟赛) [引子]还记得 NOIP 2012 提高组 Day2 中的借教室吗?时光飞逝,光阴荏苒,两年过去了,曾经借教 ...

  3. CH Round #72树洞[二分答案 DFS&&BFS]

    树洞 CH Round #72 - NOIP夏季划水赛 描述 在一片栖息地上有N棵树,每棵树下住着一只兔子,有M条路径连接这些树.更特殊地是,只有一棵树有3条或更多的路径与它相连,其它的树只有1条或2 ...

  4. CH Round #30 摆花[矩阵乘法]

    摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...

  5. contesthunter CH Round #64 - MFOI杯水题欢乐赛day1 solve

    http://www.contesthunter.org/contest/CH Round %2364 - MFOI杯水题欢乐赛 day1/Solve Solve CH Round #64 - MFO ...

  6. CH Round #17 舞动的夜晚

    舞动的夜晚 CH Round #17 描述 L公司和H公司举办了一次联谊晚会.晚会上,L公司的N位员工和H公司的M位员工打算进行一场交际舞.在这些领导中,一些L公司的员工和H公司的员工之间是互相认识的 ...

  7. CH Round #45 能量释放

    能量释放 CH Round #45 - alan有一些陷阱 III 题目描述 alan得到一块由个能量晶体构成的矿石,对于矿石中的每一个能量晶体,如果用化学物质刺激某一个能量晶体,就能使它释放能量. ...

  8. CH Round #57 - Story of the OI Class 凯撒密码

    很有意思的一道题目 考场上想的是HASH成一个整数,把末位asicc码值*1,依次乘*10,得到一个整数,然后利用等差性.唯一性快排Nlogn乱搞的 证明如下: 对于明文abcde 密文 bcdef ...

  9. Codeforces Beta Round #40 (Div. 2)

    Codeforces Beta Round #40 (Div. 2) http://codeforces.com/contest/41 A #include<bits/stdc++.h> ...

随机推荐

  1. hdu 4585 Shaolin(STL map)

    Problem Description Shaolin temple is very famous for its Kongfu monks.A lot of young men go to Shao ...

  2. Python进阶(面向对象编程基础)(二)

    1.初始化实例属性 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'ziv·chan' #定义Person类的__init__方法 ...

  3. google login page

    </pre><pre name="code" class="html"><div class="container&qu ...

  4. gcc总结【基本用法】【选项】【动静态库】(转)

    1.////////////////////////////////////////////////////////////////////////////////////////////////// ...

  5. Senparc.Weixin.MP SDK 微信公众平台开发教程 索引

    Senparc.Weixin.MP SDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到比较稳定的版本,这个过程中我觉得有必要整理一些思路和经验,和大家一起分享. ...

  6. 关于.net根目录路径的问题

    今天做了一个项目,用了url重写,但是在本地目录是localhost/BK/index.aspx,而其他目录也必须带bk,不带的话就找不到页面,(iis里正常) 应该主目录去掉bk,设置方法,右击网站 ...

  7. 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

    如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...

  8. php 之 数据访问 增删改查

    一.建立主页面: <title>主页面</title> </head> <body> <h1>主页面</h1> <tabl ...

  9. POJ2002 二分查找&哈希

    问题重述: 给定整数n,以及n个点的坐标xi, yi.求这n个点可以组成的正方形的数目(每个点可重复使用). 分析: 根据正方形的性质,给定两个点就能确定可能构成的两个正方形的另外两个顶点.因此,只需 ...

  10. Grunt使用心得

    1.安装npm 2.安装CLI ( npm install -g grunt-cli) 3.安装grunt (npm install grunt --save-dev) 4.添加gruntfile.j ...