2011年10月25日
摘要: UVA_10746 这个题目可以用最小费用最大流去做,为了复习一下二分图最优匹配,所以写了一个KM的程序。 一开始由于之前没有处理过double的KM,本来打算先把小数乘10的某次方化成整数来做,但发现一直WA,后来干脆就用double去写了,之后就AC了。#include<stdio.h>#include<string.h>#include<math.h>#define MAXD 30#define INF 1000000000int N, M, xM[MAXD], yM[MAXD] ,visx[MAXD], visy[MAXD];;double G[MA 阅读全文
posted @ 2011-10-25 19:43 Staginner 阅读(575) 评论(0) 推荐(0) 编辑
摘要: UVA_563 这个题目我们可以引入一个源点与抢劫点相连,引入一个汇点和逃脱的各点相连,然后看最大流是否和抢劫点的数量相等即可。由于限制了每个点的容量为1,因此我们可以对每个点进行拆点,然后两点之间连一条容量为1的有向边。#include<stdio.h>#include<string.h>#define MAXD 7200#define MAXM 36000#define INF 1000000000int S, A, B, e, first[MAXD], next[MAXM], u[MAXM], v[MAXM], flow[MAXM];int d[MAXD], q[ 阅读全文
posted @ 2011-10-25 19:05 Staginner 阅读(485) 评论(0) 推荐(0) 编辑
摘要: UVA_753 我们可以把适配器看做一条有向边,而插头和插座分别看成两个点,同时引入一个源点与devices相连,引入一个汇点与receptacles相连,同时由于适配器是无限量的,所以适配器这条有向边的边权为INF,而源点与devices相连的以及receptacles和汇点相连的有向边的边权为1。 建好图后求源点到汇点的最大流即可,然后用m减去最大流就是最终结果。 但其实,适配器作用实际上就是将device和相应的receptacle连接起来,因此,我们可以用Floyd根据当前适配器的种类求出每个device所能够直接或间接连接的receptacle,这样我们只要用匈牙利算法求一个二... 阅读全文
posted @ 2011-10-25 16:02 Staginner 阅读(619) 评论(0) 推荐(0) 编辑
摘要: UVA_10803 在建图的时候需要过滤掉长度大于10的边,然后用floyd求任意两点间的最短路,然后找到最短路中的最大值即可。#include<stdio.h>#include<string.h>#include<math.h>#define MAXD 110#define INF 1000000000int N;double f[MAXD][MAXD], x[MAXD], y[MAXD];double sqr(double x){ return x * x;}void init(){ int i, j; scanf("%d", &am 阅读全文
posted @ 2011-10-25 14:46 Staginner 阅读(354) 评论(0) 推荐(0) 编辑
摘要: UVA_658 这个问题纠结了比较久了,后来做另外一道题目的时候悠然告诉我说一般用二进制表示状态运算起来更快一些,这样一行就可以用一个数字去表示其状态了。按这个思路继续想下去就是如何建图了,其实无论邻接表还是邻接矩阵貌似建完整图的时间复杂度都比较大,而且好多状态未必用的到,因而不如干脆不建完整图,每次都扫描一遍转换规则,如果可以生成另一个状态就将另一个状态直接入队即可。 这样写下来时间还是比较多,后来看了别人的解题报告,发现在判定当前状态是否可以转换的时候可以直接用位运算去操作: ①判定某些位置是否为1,如判定2、4位置为1,则转化为判断x|0101是否等于x。 ②判定某些位置是否为0... 阅读全文
posted @ 2011-10-25 10:21 Staginner 阅读(974) 评论(0) 推荐(0) 编辑
摘要: UVA_104 这个题目实际上是在求一个汇率乘积大于等于1.01的最小环。由于数据量不大,我们可以直接用动规+floyd解决,设f[i][j][k]为由i到j经过k次转换所能达到的最大汇率乘积,每循环一次k我们就扫描一遍f[i][i][k],如果有大于1.01的情况就直接打印结果即可。 在记录路径时用path[i][j][k]记录第k次转换的初始位置,打印时采用递归的方式。#include<stdio.h>#include<string.h>#define MAXD 30#define MAXM 10010int N, path[MAXD][MAXD][MAXD];do 阅读全文
posted @ 2011-10-25 10:07 Staginner 阅读(839) 评论(1) 推荐(0) 编辑
摘要: UVA_125 由于a->b的路径条数等于a->i与i->b的路径条数的乘积之和,因此在用floyd的过程中我们就可以算出a->b之间的路径条数,同时,如果a->b有无线条路径的话,那么一定存在a->b路径上的某点k使得f[k][k]!=0的。#include<string.h>#include<stdio.h>#define MAXD 110int M, N, f[MAXD][MAXD];void init(){ int i, j, a, b; N = 0; memset(f, 0, sizeof(f)); for(i = 0; i 阅读全文
posted @ 2011-10-25 09:57 Staginner 阅读(506) 评论(3) 推荐(0) 编辑
摘要: HDU_3879由于最终收益=所有可能收益-(损失的收益+架设费用),因此我们可以转而用最小割去求损失的收益与架设费用之和。在建图的时候源点与用户相连,容量为每个用户带来的收益,架设点与汇点相连,容量为架设每个点所需的费用,之后将用户需要的两个点与该用户相连,容量为INF。建好图之后,左边的流量就代表损失的收益,右边的流量就代表架设费用之和,之后求此图的最小割即可。#include<string.h>#include<stdio.h>#define MAXD 60000#define MAXM 400000#define INF 1000000000int first[ 阅读全文
posted @ 2011-10-25 09:43 Staginner 阅读(360) 评论(0) 推荐(0) 编辑