poj题解
poj题解
gronkie
一个大三咸鱼罢了,如果有什么问题,欢迎私信或者评论讨论,不过实力有限,还请多多包涵
展开
-
poj1274(二分图匹配)
(一道基础的二分图匹配) 题目意思大概为N个牛和M个栅栏,一个牛和一个栅栏只能匹配一次,求最大匹配 直接套用二分图最大匹配模板即可 #include <iostream> #include <stdio.h> #include <vector> using namespace std; vector<int> data[505]; int match[505]; bool used[505]; void add_edge(int from, int to) {原创 2021-10-29 20:34:22 · 154 阅读 · 0 评论 -
poj3068(最小费用流)
(和poj2135很像很像,就多了一个情况而已,基础入门题) 题目大概意思为总共有N个仓库,求两条不同路径从起点到达终点,若是没有两条,打出Not possible,若是有可能打出所需最小费用 很简单把每个边容量设为1,费用则为题目所给,然后把起点和终点之间连一个很大很大的值,若是不足两条,费用就会变得很大很大,很容易判断出来,然后套最小费用流模板即可 (按题目所说的话,不仅边不能相同,点也不能相同,但可能样例比较松,不考虑点不重复也能过,如果想严谨的话,可以把一个点分为两个点来看,之间连一条容量为1,费用原创 2021-10-27 22:11:49 · 180 阅读 · 0 评论 -
poj3171(dp + 线段树)
(和 poj1769 几乎一样,利用线段树dp的基础题) 题目大概意思为选几个区间,使 M 到 E 全都被覆盖,求选取区间的最少数量 (我们把从 M 到 E 转化成从 1 到 E - M + 1 ) 且对于输入我们需要先排序排序一下 dp[i][j] : 意思为到第 i 个区间为止,能 刚好 覆盖到 j 的最小区间数目 例:区间为【1,10】,【5,20】,则 dp[1][10] = 1; dp[2][20] = 2; dp[2][19] = INF; 此时影响当前阶段的只有前一阶段的状态,无后效性,所以原创 2021-11-03 19:16:36 · 194 阅读 · 0 评论 -
poj3692(二分图最大独立集)
#include <iostream> #include <stdio.h> #include <vector> #include <string.h> using namespace std; vector<int> data[205]; bool ddd[205][205]; int match[205]; bool used[205]; void add_edge(int from, int to) { data[from].push原创 2021-10-26 20:31:08 · 199 阅读 · 0 评论 -
poj1486(二分图必须边)
(感觉是一个比较基础的求二分图必须边) 题目意思大概为给几个范围N,再给几个点M,如果点在范围内,就相当于可以匹配在一起,最后求必须边 首先把范围和在范围内的点连接在一起,即所有边都连接范围与点,所以是二分图 然后对于每个范围N遍历,若该范围能与多个点连接后,都能完全匹配,则说明 这个输出需要仔细(没仔细看,被卡到wa了十几次) #include <iostream> #include <stdio.h> #include <string.h> #include <原创 2021-10-26 17:17:23 · 149 阅读 · 0 评论 -
poj2195(最小费用流)
(最小费用流的入门基础题) 题目大概意思为在一个矩阵中,有n个小人和n个房子,小人每走一格花费1美元,小人只能上下左右走,且可以经过房子但不进去,为了让每个小人有自己的房子,求最小费用 首先统计每个小人去每个房子分别最少需要多少钱, 小人到房子所需费用等于两者的横坐标差的绝对值加上纵坐标差的绝对值。然后把小人与房子之间连上一条容量为1,费用为到达所需费用的值 然后套最小费用流模板即可 (其他细节我就注释在代码中) #include <iostream> #include <stdio.h&原创 2021-10-28 09:23:33 · 250 阅读 · 0 评论 -
poj2217详解 ( 后缀数组 + 高度数组 )
#include <iostream> #include <stdio.h> #include <string> #include <algorithm> using namespace std; string S; int sa[20005], rk[20005], tmp[20005], lcp[20005]; int k; bool cmp(int a, int b) { if(rk[a] == rk[b]) { int原创 2021-11-25 07:45:54 · 249 阅读 · 1 评论 -
poj3678详解(2-SAT)
题目大概意思为,有 N 个数(每个数都是 0 或 1),有 M 对关系,例 a b c AND,就是第 a 个数和第 b 个数进行 AND, 结果为 c,问是否存在能符合所有关系的这 N 个数 每个数要不为 0,要不为 1,且有限制条件(每个限制条件中变量个数不超过 2 ),考虑 2-SAT #include <iostream> #include <stdio.h> #include <vector> #include <string.h> #include原创 2021-11-09 19:06:47 · 190 阅读 · 0 评论 -
poj1466(二分图最大独立集)
题目大概意思即求一个点集,使男女互没关系 求两两互不相交的顶点集合,即求独立集 有公式 : |最大独立集| + |最小顶点覆盖| = |所有点集合| 又由于所有边连接男和女,所以为二分图 二分图问题中 : |最大匹配| = |最小顶点覆盖| 所以求 : |最大独立集| = |所有点集合| - |最大匹配| 先二分图匹配,然后用顶点数减去匹配数即可(基础题) #include <stdio.h> #include <iostream> #include <vector> #原创 2021-10-26 19:24:02 · 301 阅读 · 0 评论 -
poj3683(2-SAT)
#include <iostream> #include <stdio.h> #include <vector> #include <string.h> using namespace std; struct ddd { int start, over, spend; }data[1005]; vector<int> edge[2005]; vector<int> redge[2005]; vector<int> f原创 2021-11-06 11:04:37 · 126 阅读 · 0 评论 -
poj2112(floyd+二分+二分图多重匹配)
(感觉是一个比较基础的二分图多重匹配) 题目意思大概就是有K个挤奶点,C个奶牛,一个挤奶点能容下M个奶牛,问如果所有奶牛都被放入挤奶点时,距离最远奶牛得最短距离(距离可以经过其他点) 首先看到可以经过其他点,就直接无脑用floyd,求出各个点之间得最短距离 然后要求的是最远距离最短情况,用二分求解 (注意:二分的范围需要考虑清楚,并不是200,因为可能要经过别的路到达,所以应该设大点,200*200能过,实在不放心,10的九次方也能过) 最后就是二分判断条件,即二分图多重匹配,用一个match数组存储C匹配原创 2021-10-25 10:51:11 · 201 阅读 · 0 评论 -
poj3686(最小费用流)
题目大概意思为有N个玩具,M个工厂,每个工厂一次只能生产一个玩具,顺序任意,求所有玩具的加工完的平均时间最小值 例:N = 3 M = 2 Z = {{1,100},{100,1},{1,100}} 就相当于第一个在一工厂加工完花了 1 时间,第二个在二工厂加工完花了 1 时间,第三个在一工厂要等第一个做完再做,花了 2 时间,所以总共花了 4 时间,平均花了1.333333 假设一个工厂里有num个玩具来加工,则在该工厂所花的时间为 T = num * t_1 + (num - 1)原创 2021-10-29 22:08:24 · 195 阅读 · 0 评论 -
poj3680(最小费用流 + 拆点)
(又是一道简单的最小费用流的题目) 题目大概意思为有N个带权的开区间,现在从中选取一些区间,使任意点都不能被超过k个区间覆盖,求最大权重和 首先我们求得是最大的权重和,所以我们把 权重 ,看为 -权重 ,来求最小费,最后求个绝对值即可 然后每个区间只能选一次,考虑拆点,每个点拆为两个,连接一条容量为1,费用为 -权重 设置一个超级源点和超级汇点连接每个点,边的容量为1,费用为0(因为不确定从哪个区间开始覆盖,和从哪个区间结束) 将两个不相交(b[i] <= a[i])的区间相连,容量为1,费用为0(这原创 2021-10-29 16:33:45 · 197 阅读 · 0 评论 -
poj3422(最小费用流 + 拆点)
题目大概意思为有一个N × N矩阵,每个格子里都有一个非负数,一辆车从左上方的网格移动到右下方的网格k次(车只向右或向下移动)。每次访问格子后,其替换为0,且将其加入到金额中。求第k次旅行后能得到的最大金额是多少。 #include <iostream> #include <stdio.h> #include <utility> #include <stdlib.h> #include <vector> #define INF 100000005原创 2021-10-29 10:58:26 · 166 阅读 · 0 评论 -
poj2724(二分图匹配)
题目大概意思为有部分奶酪需要处理,若两个奶酪的二进制只有一位不同,则可以一起处理,问最少需要处理几次 题目思路: 将可以一起处理的两个奶酪用边连接在一起,相当于边只连接二进制中有偶数个1的奶酪和二进制中有奇数个1的奶酪,因此是个二分图 每匹配成功一次,相当于可以少处理一次,所以结果等于所有需要处理的奶酪数减去最大匹配数 (基础题,无难点) 做法: 将题目给的输入转化为数,然后去重,把所有数中,二进制只有一位不同的两个数连接在一起,然后二分图匹配,最后拿所需处理的奶酪数减去结果即可ac #include &l原创 2021-10-27 10:20:18 · 122 阅读 · 0 评论 -
poj2186(强连通分量分解)
题目大概意思为有 N 头牛,有些牛认为有些牛是红人,该关系具有传递性,例如果牛A觉得牛B是红人,牛B认为牛C是红人,则牛A也会认为牛C是红人,求被其他所有牛认为是红人的牛的总数 假设被其他所有牛认为是红人的牛的点集为 S ,由于被是被其他所有牛觉得是红人,因此最后点集内的牛,都互相认为是红人,所以为强连通分量 我们将原图强连通分量分解后,只有最接近图的末尾的强连通分量有可能是题目结果,因此我们取强连通分量中编号最后的强连通分量 点集S(即图最末尾的)进行判断 取 点集S 中任意一点(该点集内互通,所以取哪一原创 2021-11-05 15:59:47 · 216 阅读 · 0 评论 -
poj2723详解(二分 + 2-SAT)( 两种方法求解 )
题目大概意思为有 N 对锁(即有 2N 个锁),每对锁只能用其中一种,用了一种后,另一种会消失,有M 个大门,每个门有两个锁,开了其中一个就能打开门,问能从第一个门开始,一个个按顺序打开,最多打开多少门 二选一,有限制条件,考虑 2-SAT 求的是最大可行解,考虑 二分 第一种: 我们考虑每个门之间的关系,例如有一对钥匙为 1 2 ,而门1 为 0 1,门2 为 0 2,这样如果选了 门1 的 锁1,则 钥匙2 消失,我们就必须选择 门2 的 锁0 (但是我们如果这样考虑每个门之间的关系,这样的代码复杂度为原创 2021-11-08 18:19:13 · 161 阅读 · 0 评论 -
poj3484详解(二分)
(一道思路不错的二分,但是这题比较难看懂,并且输入有点恶心!) 题目大概意思为每个数据给你 n 组数,问这 n 组数中哪个数出现的次数为奇数(保证只有一个数) 每组数给的方式为 X , Y , Z 这组数即为 X , X + Z , X + 2 * Z , X + 3 * Z , … , X + K * Z , …(当 ( X + K * Z ) <= Y 时) 输入就不说了,到时候看代码 这道题我们这么考虑,因为除了所求的数 n 的所有数出现的次数都为奇数,且 偶数 + 奇数 = 奇数, 那么 n原创 2021-11-11 20:36:59 · 433 阅读 · 0 评论 -
poj2226(最小顶点覆盖)
(相当于是poj3041的进阶版,不过难度还好) 题目大概意思为将一个矩阵中的泥泞部分给覆盖起来,可以横着覆盖也可以竖着覆盖,但不能覆盖到其他草地部分,覆盖的板子长度随意,宽度为1,可以重复覆盖,求最少需要的板子数量 解题思路:把板子当成图的顶点,把泥泞的点当作连接对应板子(一个横着的,一个竖着的)的边,这样转化之后,求最少需要的板子数量,即相当于我们对于任意边,都至少需要一个该边的端点,即转为成了求最小顶点覆盖问题。 由于所有的泥泞的点,连接的都是横着的和竖着的,所以这是二分图,在二分图中,|最小顶点覆盖原创 2021-10-27 19:52:33 · 381 阅读 · 0 评论 -
poj1769(dp + 线段树)
题目大概意思为选几个区间,使 1 到 n 全都被覆盖,求选取区间的最少数量 dp[i][j] : 意思为到第 i 个区间为止,能刚好覆盖到 j 的最小区间数目 例:区间为【1,10】,【5,20】,则 dp[1][10] = 1; dp[2][20] = 2; dp[2][19] = INF; 此时影响当前阶段的只有前一阶段的状态,无后效性,所以 dp 可行 预处理,i = 0时,dp[0][] = 0; dp[0][j] = INF; ( 从 1 开始,所以不用区间就能到 1 ) 那 dp[i+1][j]原创 2021-11-02 23:34:55 · 213 阅读 · 0 评论