[HZNOI #514] Magic

题意

给定一个 \(n\) 个点 \(m\) 条边的有向图, 每个点有两个权值 \(a_i\) 和 \(b_i\), 可以以 \(b_i\) 的花费把第 \(i\) 个点的 \(a_i\) 变成 \(0\). 最后每个点 \(i\) 产生的花费为所有从 \(i\) 出发能通过一条有向边直接到达的点 \(j\) 的 \(a_j\) 的 \(\max\). 最小化这个过程中的总花费.

\(n\le 1000,m\le50000\)

题解

一点都不套路的最小割.

果然我是不会网络流的.

对于每个点, 如果将它的邻接点按照 \(a_j\) 降序排序的话, 不难发现必然要干掉一个前缀的所有 \(a_j\) 才能让这个点在最后统计的时候产生的花费变小. 但是多次干掉同一个点不能重复计算花费.

那么我们一点都不自然地想到最小割. 先把所有点拆成两个, 一个负责计算最终统计时的花费 (A类点), 一个负责计算被干掉的时候产生的花费 (B类点). 被干掉的时候产生的花费直接连一条流量为 \(b_i\) 的边到 \(t\) 就可以了. 最终统计时的花费先从 \(s\) 连一条 \(\infty\) 边到当前点, 然后按照 \(a_j\) 降序拉出一条链来, 链上的每个点代表一条边, 权值为这条边到达的点的 \(a_j\). 然后再从链上的每个点连一条 \(\infty\) 边到 \(j\) 对应的点. 这样的话如果 \(s\verb|-|t\) 被割断, 那么对于每一个 A 类点, 后面必然是割掉了某个 \(a_j\), 同时所有大于被割断的 \(a_j\) 的边邻接的点必然都已经被割掉了 \(b_i\).

建图Dinic就可以了.

这个拉链然后最小割的套路依然没有学会...果然我还是太菜了QAQ...

什么你问我 \(n+m\) 个点Dinic怎么跑过去的? 我怎么知道?Dinic的运行速度大概都是靠信仰吧...

恋恋世界第一!

参考代码

#include <bits/stdc++.h>

const int MAXV=1e5+10;
const int MAXE=5e6+10;
const int INF=0x7FFFFFFF; struct Edge{
int from;
int to;
int flow;
Edge* rev;
Edge* next;
};
Edge E[MAXE];
Edge* head[MAXV];
Edge* cur[MAXV];
Edge* top=E; int v;
int e;
int a[1010];
int b[1010];
int depth[MAXV];
std::vector<int> link[1010]; bool BFS(int,int);
int Dinic(int,int);
int DFS(int,int,int);
void Insert(int,int,int); int main(){
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
scanf("%d%d",&v,&e);
for(int i=1;i<=v;i++)
scanf("%d",a+i);
for(int i=1;i<=v;i++)
scanf("%d",b+i);
for(int i=0;i<e;i++){
int a,b;
scanf("%d%d",&a,&b);
link[a].push_back(b);
}
for(int i=1;i<=v;i++)
std::sort(link[i].begin(),link[i].end(),[](int a,int b){return ::a[a]>::a[b];});
int s=0,t=1,cnt=v*2+1;
for(int i=1;i<=v;i++){
Insert(s,i+1,INF);
Insert(i+v+1,t,b[i]);
int last=i+1;
for(size_t j=0;j<link[i].size();j++){
++cnt;
Insert(cnt,v+link[i][j]+1,INF);
Insert(last,cnt,a[link[i][j]]);
last=cnt;
}
}
printf("%d\n",Dinic(s,t));
return 0;
} int Dinic(int s,int t){
int ans=0;
while(BFS(s,t))
ans+=DFS(s,INF,t);
return ans;
} bool BFS(int s,int t){
memset(depth,0,sizeof(depth));
std::queue<int> q;
q.push(s);
depth[s]=1;
cur[s]=head[s];
while(!q.empty()){
s=q.front();
q.pop();
for(Edge* i=head[s];i!=NULL;i=i->next){
if(i->flow>0&&depth[i->to]==0){
depth[i->to]=depth[s]+1;
cur[i->to]=head[i->to];
if(i->to==t)
return true;
q.push(i->to);
}
}
}
return false;
} int DFS(int s,int flow,int t){
if(s==t||flow<=0)
return flow;
int rest=flow;
for(Edge*& i=cur[s];i!=NULL;i=i->next){
if(i->flow>0&&depth[i->to]==depth[s]+1){
int tmp=DFS(i->to,std::min(rest,i->flow),t);
if(tmp<=0)
depth[i->to]=0;
rest-=tmp;
i->flow-=tmp;
i->rev->flow+=tmp;
if(rest<=0)
break;
}
}
return flow-rest;
} inline void Insert(int from,int to,int flow){
top->from=from;
top->to=to;
top->flow=flow;
top->rev=top+1;
top->next=head[from];
head[from]=top++; top->from=to;
top->to=from;
top->flow=0;
top->rev=top-1;
top->next=head[to];
head[to]=top++;
}

[HZNOI #koishi] Magic的更多相关文章

  1. Codeforces CF#628 Education 8 D. Magic Numbers

    D. Magic Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  2. [8.3] Magic Index

    A magic index in an array A[0...n-1] is defined to be an index such that A[i] = i. Given a sorted ar ...

  3. Python魔术方法-Magic Method

    介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...

  4. 【Codeforces717F】Heroes of Making Magic III 线段树 + 找规律

    F. Heroes of Making Magic III time limit per test:3 seconds memory limit per test:256 megabytes inpu ...

  5. 2016中国大学生程序设计竞赛 - 网络选拔赛 C. Magic boy Bi Luo with his excited tree

    Magic boy Bi Luo with his excited tree Problem Description Bi Luo is a magic boy, he also has a migi ...

  6. 一个快速double转int的方法(利用magic number)

    代码: int i = *reinterpret_cast<int*>(&(d += 6755399441055744.0)); 知识点: 1.reinterpret_cast&l ...

  7. MAGIC XPA最新版本Magic xpa 2.4c Release Notes

    New Features, Feature Enhancements and Behavior ChangesSubforms – Behavior Change for Unsupported Ta ...

  8. Magic xpa 2.5发布 Magic xpa 2.5 Release Notes

    Magic xpa 2.5發佈 Magic xpa 2.5 Release Notes Magic xpa 2.5 Release NotesNew Features, Feature Enhance ...

  9. How Spring Boot Autoconfiguration Magic Works--转

    原文地址:https://dzone.com/articles/how-springboot-autoconfiguration-magic-works In my previous post &qu ...

随机推荐

  1. Spring 3.1新特性之二:@Enable*注解的源码,spring源码分析之定时任务Scheduled注解

    分析SpringBoot的自动化配置原理的时候,可以观察下这些@Enable*注解的源码,可以发现所有的注解都有一个@Import注解.@Import注解是用来导入配置类的,这也就是说这些自动开启的实 ...

  2. 【JS】input输入框只能输入数字

    一.实现思路 input只能输入纯数字的思路其实很简单,监听输入框值的变化,每次输入检索输入框的值,将非数字的字段替换成空,再将此值赋予给输入框. 关键代码: \d:匹配数字 ^/d:全文匹配非数字 ...

  3. Spring Import注解

    今天了解了,Spring @Import的使用 先贴上Spring官方关于Spring @Import注解的文档链接   https://docs.spring.io/spring/docs/3.0. ...

  4. 百度前端技术学院-task2.18-2.19源码以及个人总结

    源码:http://yun.baidu.com/share/link?shareid=2310452098&uk=1997604551 1.感觉在写js的时候,最好先理清思路,先干什么,在干什 ...

  5. 【PAT 甲级】1151 LCA in a Binary Tree (30 分)

    题目描述 The lowest common ancestor (LCA) of two nodes U and V in a tree is the deepest node that has bo ...

  6. [转]解决ssh登录后闲置时间过长而断开连接

    本文转自: 转载自博客园wanghetao的博客 我们通过终端连接服务器时,当鼠标和键盘长时间不操作,服务器就会自动断开连接,我们还的需要重新连接,感觉很麻烦,总结一下解决此问题的方法 方法一 修改/ ...

  7. iphone safari浏览器CSS兼容性的解决方案集合

    1.iphone safari不兼容CSS的active的解决方案如下: <body ontouchstart="" onmouseover=""> ...

  8. asp.net的get和post请求

    asp.net的get和post请求 //获取第三方api的工具类 public class HttpUtils { public static string Get(string Url) { // ...

  9. 2.移植3.4内核-支持烧写yaffs2,裁剪内核并制作补丁

    在上章-制作文件系统,并使内核成功启动jffs2文件系统了 本章主要内容如下: 1)使内核支持yaffs2文件系统 2)裁剪内核 3)制作内核补丁 1.首先获取yaffs2源码(参考git命令使用详解 ...

  10. Java读取excel(兼容03和07格式)

    读取excel,首先需要下载POI的jar,可以去官网下,也可以在这里下载 一.简单说明 excel2003和excel2007区别比较大,最直观的感受就是扩展名不一样,哈哈 不过,使用POI的API ...