摘要:这题WA很久,然后找不出原因,后来看了书上的程序(图论理论算法实现及应用神马的),然后感觉不出来自己哪里错了,后来改了改,把无穷大的定义改小了点,再放到ZOJ上,成功AC了,我都不知道为什么,也许还改了其他地方,我已经糊涂了,然后又把它放POJ 1135上又WA了,我都憔悴了,最后我想起以前刷水题时要把double用%f输出,我试了一下,果然AC了,求解释`````贴代码:View Code 1 #include <cstdio> 2 #include <cstring> 3 #define MAXN 505 4 #define INF 1000000 5 int n;
阅读全文
摘要:这个题绝对的Prim,但是这题有个怪一点的地方,他的适配器要重复买,比如顶点A和B连了一条边,顶点B和C连了一条边,那么要买,两个B适配器,一个A和一个C适配器,我先理解错了,以为只要买一个B适配器就可以了,所以连测试数据都过不了。然后可以直接把两个适配器的价格算在这条边的权值上,反正总的要求是造价最低嘛。。。贴代码:View Code 1 #include <cstdio> 2 #define MAXN 1020 3 int n; 4 int sum; 5 int lowcost[MAXN]; 6 int edge[MAXN][MAXN]; 7 void Prim() 8 { 9
阅读全文
摘要:就是Prim算法,求最小生成树,把每个汽车编号看成点,两个编号的距离,也就是相同位置不同字符的数目,就看做边,显然,看成无向图,谁生成谁自己想想就行了 ,这里边比较多,用Prim算法。代码:View Code 1 #include <cstdio> 2 #define MAXN 2005 3 int n; 4 int lowcost[MAXN]; 5 int edge[MAXN][MAXN]; 6 int dis(char a[],char b[]) 7 { 8 int s = 0; 9 for(int i=0; i<7; i++)10 if(a[i] != ...
阅读全文
摘要:和ZOJ 1203解法一样,不赘述,我都直接复制的代码修改了一下贴代码:View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #define MAXN 1020 6 #define MAXM 15020 7 using namespace std; 8 int n,m; //n为顶点个数,m为边数 9 struct ArcNode10 {11 int u,v; //一条边的起点和终点12 int w; //边的权
阅读全文
摘要:就是如题的做法,在一个连通图中找一条最小生成树,Kruskal的思想就是先根据所有边的权值按小到大排序,然后依次选择边进最小生成树里,但是要排除该边加进去后出现了环,生成树里是不能有环的,这样的边就不能加入,在挑选了n-1(n为图中点的个数)条边后就结束,可以证明这样构造出来的图就是最小生生成树。再判断是否会出现环时用到并查集。int temp = parent[r1] +parent[r2];//两根结点所带结点的总数,因为写错了这句,我检查了N久,砸墙,我很激动地写成了 int temp = Find(r1)+Find(r2);然后各种程序各种混乱了。还有一点因为没有看见说每两个case中
阅读全文
摘要:这个题我是看书上解题思路做的,自己未必想的出来,就是根据他给你的窗口分布去构造图,比如说这个格子本来可以被1,2,4,5窗口共用(只是指1,2,4,5都能出现在这个格子上,但是一次当然只可能出现一种情况),现在被2占用了,那么2可能是覆盖了1,4,5窗口,这样就构造有向边<2,1>,<2,4>,<2,5>如此类推,把整个图构造出来后,出现环了 ,证明电脑坏掉了,鉴于我相当水,只好用拓扑排序写,因为一共也就9个点,尽管拓扑时间复杂度高,但数据小,也就还能接受啦,不会超时。我0MS过的。如果可以,建议尽量用别的各种方法去判环。这题我也WA好多次,这次是因为忘了注
阅读全文
摘要:这题就是拓扑排序,但是能确定的情形必须是拓扑序列唯一。做法是在读边的时候 ,读完一条边后就调用topsort函数,如果通过topsort函数能确定出现环,则矛盾,或者存在了把所有 n个字母都包括进去了的唯一拓扑序列。就可以输出结果,以后就不调用topsort函数了。但是注意剩下的数据要读完,当读完所有的边上述两种情况都还没有出现,就可以输出不能确定了我是这样做的,在做拓扑排序时,先把入度为0的顶点入栈,该顶点入度设为-1(这样就不会重复入栈)如果出现两入度为0,可以知道不存在唯一拓扑序列了,别急,要接着做拓扑排序,从栈中 pop出元素,所有是该顶点后继的顶点的入度减一,再找入度为0的顶点入栈,
阅读全文
摘要:思路是把物品看成是无限的,就像做完全背包一样从小到大更新,而事实上每种物品的数量却是有限的,所以还必须用count[j]记录当拼成j面值时用了多少个面值为ai的硬币,当在考虑面值k能否拼成时,如果count[k-ai]时已经用掉了re个ai面值的硬币了,如果re >= 该面值硬币的数量了,面值k就不能拼成,因为没这么多硬币了,如果小于该面值硬币的数量,面值 k能拼成,且count[k]为count[k-ai]+1.View Code 1 #include <cstdio> 2 #include <cstring> 3 bool v[100010]; 4 int c
阅读全文
摘要:http://blog.csdn.net/diannaok/article/details/7875086?reload我是看着他的写的,但是有个小错误,在初始化值时,令>L/2中最大的数的初始值为L+1较为合适,想想1 3 3 1 4这组测试数据。这题我再详细说一下,我们试想在子集中最大的那个数怎么取,如果取<=M/2那么所有<=M/2的数一定都可以取,但是如果取一个>M/2的数的话,那么该子集只能取一个>M/2的数,取两个的话不就不满足yi+yj <= L了嘛,如此说来,就在>M/2的数中取一个最小的,在<=M/2的数中取最大的,如果加起来&
阅读全文
摘要:就是每个组中只要选择一种,然后0-1背包一下。View Code 1 #include <cstdio> 2 #include <cstring> 3 int main() 4 { 5 int n,m; 6 while(~scanf("%d%d",&n,&m)) 7 { 8 int f[200],A[200][200]; 9 if(n == 0 && m == 0) break;10 for(int i=0; i<n; i++)11 for(int j=1; j<=m; j++)12 ...
阅读全文
摘要:像这种恰好装满的情况可以用bool数组,恰好装满为true,否则为false。还有就是逆向推倒,0-1背包,f[i][j]表示有i个人,组成了j的体重,这样的话在考虑某人的情形时,f[i][j]为真的前提就是f[i-1][j-wi]为真,其中wi为这个人的体重View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 bool f[110][2500]; 5 int main() 6 { 7 int n,w[110],sum = 0; 8 scanf("%d\n&q
阅读全文
摘要:这题WA了很多遍,要不就是测试数据 3 1 2 3 输出173,要不就是6 5 5 5 5 5 5 输出-1.甚至有时候把程序改的题目上的测试数据都过不了,各种悲摧,其实我喜欢边写程序边想,这是个很差的习惯,我一定要改!!!这题是看别人的提示写出来的,首先设bool型数组f,令 f[i][j]表示一边长为i,另一边长为j的边可以组合出来,然后在所有可以组合出来的情形中找能组合成三角形且面积最大的。f[i][j]能组合出来的条件是对于加入新边li来说是f[i-li][j] 或f[i][j-li]能组合出来,初始条件是f[0][0]能组合出来。因为题目中说了要用掉所有的栏杆,所以我只考虑两条边,剩
阅读全文
摘要:二进制压缩,看背包九讲啦,写的很详细了,不赘述````先贴不要求恰好装满的情形POJ 1276二进制压缩: 1 #include <cstdio> 2 #include <cstring> 3 int f[100005];//容量为i时最多能装多少 4 int p[12000];//物品拆分 5 int main() 6 { 7 int n,cash; 8 while(~scanf("%d%d",&cash,&n)) 9 {10 int vi,num;//物品价值,数量11 int cur = 0;12 memset(f,...
阅读全文
摘要:顺序求解是完全背包,逆序求解是0-1背包,自己想想View Code 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 struct node 5 { 6 int cost,value; 7 } ; 8 node u[100005]; 9 int f[100005];10 int main()11 {12 int G,U;13 int T,cur;14 scanf("%d",&T);15 while(T--)16 {17 // freopen("in.
阅读全文
摘要:http://acm.zjut.edu.cn/不完全装满取值初始值都为0,恰好装满f[0]初始值为0,其他的为负无穷。得到的玩具的价格按从大到小排序,保证当玩具组合出的价格等于擎天柱价格时,玩具的数量会是最少的View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 int f[10010]; 6 int c[10010]; 7 int main() 8 { 9 int n,m;10 int p[20];11 while
阅读全文
摘要:用f[i]记录当背包容量为i时,最大的重量。那么初始状态所有f[i]=0,一个物品一个物品考察,从容量大的背包开始到容量为1的背包结束,这时所有容量小的背包肯定都还没有放入该物品,这时原有的f[i]值如果小于f[i-pi]+pi,也就是未放这物品和放这物品后的容量值做比较,发现放这物品后总的容量值增大了,就放这物品。推荐看背包九讲,网上有下载,写得很好View Code 1 #include <cstdio> 2 int f[13000];//f[i]的值为背包容量为i时得到的最大价值 3 int w[3500]; 4 int d[3500]; 5 int main() 6 { 7
阅读全文
摘要:该题的关键是如果a%n = x;则(a*10+b)%n == (x*10+b)%n。例如你要算123456789%3,你只需算((12345678%n)*10+9)%3。想法是把给你的数字先排序,然后扩展,这样能保证你拓展出的数是以递增序列出现的。按示例所示,给你数字1,7,0,你可以拓展出10,11,17;70,71,77;从拓展出的六个新的数,每个数又能拓展出M(这里的M为3)个。然后要优化处理,算所谓的剪枝吧。拓展出的数模n的余数等于原数的余数*10+增加的数,再模n.如果新数的余数已经出现过,就不入队列了,因为该数没有被拓展的必要(已经有一个比它小的数用来拓展)。如果出现某数的余数为0
阅读全文
摘要:/*该题的解题思路为BFS,从某点开始进行BFS,以层数表示到该地区的距离,用到了滚动队列。 对每个公交车的站点进行BFS,记录每个地区到该公交站的距离,遍历完后会得出每个地区到 所有公交站点的最大距离,以此知道选择了该地区后的星型阀值。然后从所有地区中选择一个 最小的*/View Code 1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #define ZMAX 10000 //地区编号的最大值 5 #define INF 100000 6 using namespace std;
阅读全文
摘要:次题的关键是把稻田的中心点抽象成图中的点,两中心点有水管相连表示两点连通,这样,此题就转化成了求图的连通分支数目View Code 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 char grid[52][52]; 6 char map[52][52]; 7 int m,n; 8 int dir[4][2] = {{-1,0},{0,1},{0,-1},{1,0}}; // 上,右,左,下 9 //编号分别为 0,1,2,310
阅读全文
摘要:该题是找满足条件的摆法,直接DFS会超时,关键是压缩存储,同一种正方形只存一次,再DFS,然后搜到一种成功的就要退出,不要把所有可能的摆法都搜完,不然也会超时。初始化种类数不要忘记。View Code 1 #include <cstdio> 2 #include <cstring> 3 bool flag ; //成功标志 4 int n,kinds; //正方形的个数为n*n,种类为kinds 5 struct square 6 { 7 int top,bottom,left,right; 8 int num; //该类正方行的个数 9 } rect[26];//记录
阅读全文
摘要:求整数a,b的最大公约数和最小公倍数先求最大公约数,辗转相除:int gcd(int a,int b){return (b == 0)? a:gcd(b,a%b);}求出最大公约数后,利用a*b = lcm(a,b)*gcd(a,b)求最小公倍数int lcm(int a,int b){ return a/gcd(a,b)*b;}
阅读全文
摘要:判断一个有限序列是否是可图的,有Havel-Hakimi定理:由非负整数组成的非增序列s:d1,d2,~~~(省略号),dn(n>=2,d1>=1)是可图的,当且仅当序列:s1:d2-1,d3-1,~~~,d(d1+1) - 1,d(d1+2),~~~,dn是可图的。序列s1中有n-1个非负整数,s序列中d1后的前d1个度数减1后构成s1中的前d1个数。据此定理可以根据一个序列构造出相应的图(结果不唯一)实例:POJ 1659 青蛙的邻居注意:给每个顶点先编好号View Code 1 #include <cstdio> 2 #include <cstring>
阅读全文