题目:你去找某bm玩,到了门口才发现要打开他家的大门不是一件容易的事……

他家的大门外有n个站台,用1到n的正整数编号。你需要对每个站台访问一定次数以后大门才能开启。站台之间有m个单向的传送门,通过传送门到达另一个站台不需要花费任何代价。而如果不通过传送门,你就需要乘坐公共汽车,并花费1单位的钱。值得庆幸的是,任意两个站台之间都有公共汽车直达。

现在给你每个站台必须访问的次数Fi,对于站台i,你必须恰好访问Fi次(不能超过)。

我们用u、v、w三个参数描述一个传送门,表示从站台u到站台v有一个最多可以使用w次的传送门(不一定要使用w次)。值得注意的是,对于任意一对传送门(u1,v1)和(u2,v2),如果有u1<u2,则有v1≤v2;如果有v1<v2,则有u1≤u2;且u1=u2和v1=v2不同时成立。

你可以从任意的站台开始,从任意的站台结束。出发去开始的站台需要花费1单位的钱。你需要求出打开大门最少需要花费多少单位的钱。

解法:由于要最小花费,那免费的传送门肯定尽量多用。而又要求每个站台必须不多不少访问 Fi 次,我们可以把每个站台拆成分成 “入度和出度”计算,也就是“到达和出发的次数”。
       接着就是贪心的思想。由题意可知,不存在 [l,r] 和 [ll,rr] 既满足 l<ll,又满足 r>rr,而且没有 l,r 都相同的传送梦。那么,我们把传送门按先起始点,再终结点从小到大的顺序排序之后,直接从前到后扫传送门,贪心每种用到极致 (•́⌄•́๑)૭✧,也就是在起始点和终结点都<= Fi 的情况下用到最多。这样可以的原因是:对于当前传送门 [l,r] 和下一个传送门 [ll,rr],若没有相等的,那么对于当前的 l 和 r 都是能减少花费就减少,因为没有其他的传送门能到达它们了。若是 l=ll,那么对于 r 就是尽量能减少花费就减少;而若是 r=rr,那就是对于 l 这样了。因此可以这样贪心。

P.S.而我下面屏蔽的代码就是没有理解“拆点”的意义。(⊙_⊙;)… 一定要拆“入和出”,否则会漏算或多算的。

 1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<algorithm>
5 #include<iostream>
6 using namespace std;
7 #define N 10010
8 #define M 100010
9 #define W 50010
10
11 int n,m;
12 int gin[N],gout[N];
13 struct node{int x,y,w;}a[M];
14
15 bool cmp(node x,node y)
16 {
17 if (x.x!=y.x) return x.x<y.x;
18 return x.y<y.y;
19 }
20 int mmin(int x,int y) {return x<y?x:y;}
21 int main()
22 {
23 int i,j,ans=0;
24 scanf("%d%d",&n,&m);
25 for (i=1;i<=n;i++)
26 {
27 scanf("%d",&gin[i]);
28 gout[i]=gin[i];
29 ans+=gin[i];
30 }
31 for (i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
32 sort(a+1,a+1+m,cmp);
33 j=1;
34 for (i=1;i<=n;i++)
35 {
36 while (j<=m && a[j].x==i)
37 {
38 int x=i,y=a[j].y;
39 int tmp=mmin(mmin(gout[x],gin[y]),a[i].w);
40 gout[x]-=tmp,gin[y]-=tmp;//直到现在能入y和出x的次数
41 ans-=tmp, j++;
42 }
43 }
44 /*for (i=1;i<=m;i++)
45 {
46 int x=a[i].x,y=a[i].y;
47 int tmp=mmin(mmin(gout[x],gin[y]),a[i].w);
48 gout[x]-=tmp,gin[y]-=tmp;
49 ans-=tmp;
50 }*/
51 /*j=1;
52 for (i=1;i<=n;i++)
53 {
54 while (j<=m && a[j].x==i)
55 {
56 int x=i,y=a[j].y;
57 //int tmp=mmin(mmin(h[x],h[y]),a[j].w);
58 //h[x]-=tmp,h[y]-=tmp;//同一个点重复计算了
59 ans-=tmp, j++;
60 }
61 }*/
62 /* int cnt=0,p=1;//x min & y min
63 for (i=2;i<=m;i++)
64 if (a[i].x!=a[i-1].x) a[++p]=a[i];//推广!因为h[i]>1,所以不删次优的边
65 p=1;
66 for (i=2;i<=m;i++)
67 if (a[i].y!=a[i-1].y) a[++p]=a[i];*/
68 printf("%d\n",ans);
69 return 0;
70 }

【bzoj 2163】复杂的大门(算法效率--拆点+贪心)的更多相关文章

  1. bzoj 2163: 复杂的大门

    2163: 复杂的大门 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 418  Solved: 259[Submit][Status][Discuss ...

  2. 【uva 11134】Fabled Rooks(算法效率--问题分解+贪心)

    题意:要求在一个N*N的棋盘上放N个车,使得它们所在的行和列均不同,而且分别处于第 i 个矩形中. 解法:问题分解+贪心. 由于行.列不相关,所以可以先把行和列均不同的问题分解为2个"在区间 ...

  3. 【bzoj 3433】{Usaco2014 Jan} Recording the Moolympics(算法效率--贪心)

    题意:给出n个区间[a,b),有2个记录器,每个记录器中存放的区间不能重叠.求2个记录器中最多可放多少个区间. 解法:贪心.只有1个记录器的做法详见--关于贪心算法的经典问题(算法效率 or 动态规划 ...

  4. CUDA并行计算 | CUDA算法效率提升关键点概述

    文章目录 前言 存取效率 计算效率 性能优化要点 展现足够的并行性 优化内存访问 优化指令执行 前言   CUDA算法的效率总的来说,由存取效率和计算效率两类决定,一个好的CUDA算法必定会让两类效率 ...

  5. 【uva 1617】Laptop(算法效率--贪心,2种理解)

    题意:有N条长度为1的线段,要求使每条线段分别在相应区间,且"空隙"数目最小.输出"空隙"数.(1≤N≤100000) 解法:(P.S.我这题竟做了2个多小时, ...

  6. 【uva 1615】Highway(算法效率--贪心 区间选点问题)

    题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到 ...

  7. 关于贪心算法的经典问题(算法效率 or 动态规划)

    如题,贪心算法隶属于提高算法效率的方法,也常与动态规划的思路相挂钩或一同出现.下面介绍几个经典贪心问题.(参考自刘汝佳著<算法竞赛入门经典>).P.S.下文皆是我一个字一个字敲出来的,绝对 ...

  8. Java 算法(一)贪心算法

    Java 算法(一)贪心算法 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 一.贪心算法 什么是贪心算法?是指在对问题进行求 ...

  9. python常用算法(6)——贪心算法,欧几里得算法

    1,贪心算法 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的的时在某种意义上的局部最优解. 贪心算法并不保证会得到最优解,但 ...

随机推荐

  1. TCP连接的建立与释放(超详细)

    前言:在计算机网络协议中,TCP只是其中一个,然而在网络使用中,TCP也是最离不开的协议之一,它的重要性毋庸置疑,最最重要的是,面试的重点就是它啊,呜呜~~,今天我们一起来看下TCP的连接建立与释放, ...

  2. 技术基础 | Cassandra RBAC助你打击“虚拟海盗”,让他们对数据“战利品”望而不得

    现如今,我们称虚拟世界里的海盗们为"黑客",他们所追寻的战利品就是在你数据库某处的数据.   而我们能够保证你的数据安全的工具之一,就是"Cassandra基于角色的访问 ...

  3. 【System】paging和swaping之间的区别是什么?

    分析paging和swapping的区别,首先要了解内存管理 当虚拟内存用二级存储(物理磁盘)作为主存的扩展时,内核会尽力保持最活跃的数据在主存中.有一下两个内核例程做这件事情: 1.交换(swapp ...

  4. Java 8中字符串拼接新姿势:StringJoiner

    介绍 StringJoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾.虽然这也可以在StringBuilder类的帮助 ...

  5. 同步与异步 Python 有何不同?

    你是否听到人们说过,异步 Python 代码比"普通(或同步)Python 代码更快?果真是那样吗? 1 "同步"和"异步"是什么意思? Web 应用 ...

  6. Spring Security 实战干货:分布式对象SharedObject

    1. 前言 在上一篇我们对AuthenticationManager的初始化的细节进行了分析,其中里面有一段代码引起了不少同学的注意: ApplicationContext context = htt ...

  7. mysql事务测试

    mysql事务测试 打开mysql的命令行,将自动提交事务给关闭 --查看是否是自动提交 1表示开启,0表示关闭 select @@autocommit; --设置关闭 set autocommit ...

  8. ShardingSphere内核原理 原创 鸽子 架构漫谈 2021-01-09

    ShardingSphere内核原理 原创 鸽子 架构漫谈 2021-01-09

  9. Hash Join: Basic Steps

    Joins https://docs.oracle.com/database/121/TGSQL/tgsql_join.htm#TGSQL242 tidb/index_lookup_hash_join ...

  10. 死锁案例 GAP 锁 没有就插入,存在就更新

    https://mp.weixin.qq.com/s/2obpN57D8hyorCMnIu_YAg 死锁案例八 文 | 杨一 on 运维 转 | 来源:公众号yangyidba 一.前言 死锁其实是一 ...