摘要:
题目大意:先解释有向无环图的路径覆盖,在图中找一些不相交的简单路径,使之覆盖图中所有顶点,且每一顶点只有一条路径与之关联,也就是说,若沿着这些路径中每条路径从起点走到终点,则可以恰好经过图中每一个顶点一次且仅一次。该题是求最小路径覆盖,即使得路径条数最小。题中的限制在顶点,将图转换为二分图,每个顶点... 阅读全文
摘要:
在一个n*n网格上有一些小行星,一发子弹可以摧毁一行或一列的小行星,问最少需要多少发子弹可以摧毁全部小行星。建立行与列的二分图,若第 i 行第 j 列有小行星则在 xi与 yj间连一条边,对于每一条边的两个顶点必须至少有一个被选择,即最小点覆盖,由konig定理,点覆盖数等于匹配数,所以用匈牙利算法... 阅读全文
摘要:
转自http://3214668848.blog.163.com/blog/static/48764919200991885836429/导弹拦截是一个经典问题:求一个序列的最长不上升子序列,以及求能最少划分成几组不上升子序列。第一问是经典动态规划,第二问直接的方法是最小路径覆盖, 但是二分图匹配的复杂度较高,我们可以将其转化成求最长上升子序列,其最大值即等于不上升子序列的最小划分数。这就涉及到组合数学中偏序集的 Dilworth定理。(第二问的贪心方法其实就是这个定理的证明过程)其中第一问和第二问都可以用o(nlogn)的算法解决:#include#include#includeusing 阅读全文
摘要:
转自http://www.cnblogs.com/fstang/archive/2013/03/31/2991220.html偏序集:We define a Partially Ordered Set, or a Poset, as a set P witha partial ordering defined on it’s elements. I.e, for any twoelements x and y of P, either x ≤ y, y≤x (x and y are comparable),or x || y (x and y are incomparable).链(ch 阅读全文
摘要:
题目是中文的~对于网格这种图是一个典型的二分图(只要无奇数长度的回路的图就是二分图),先建立二分图,对于第 i 行第 j 列的点,i + j为偶数的归为 x集合,为奇数的归为 y 集合,相邻格子间连边,这就完成了二分图的构建。题目要求取出来的值最大,且不能相邻,所以每一个点独立集都符合不相邻的要求,现在要使独立集的点权和最大,因为点独立集和点覆盖集是对应的,具体说一个图去掉任意一个点独立集剩下的点会构成一个点覆盖集,所以只需求最小点权覆盖即可。有关最小点权覆盖之前介绍过。。直接上代码吧。#include #include #define Max 30#define INF 5000000int 阅读全文
摘要:
题目大意:找出一个网络中的spf点,即割点,并输出将某spf点删除后会将原网络分割成几个连通的子网络。即求割点,用tarjan算法。#include #include int min(int a,int b){ if(a=dfn[u]) { if(u!=1) subnet[u]++; if(u==1) son++; } } else low[u]=min(low[u],dfn[v]); } }}void init(){ low[1]=dfn[1]=1; tmpdfn=1;son=0; memset(vis,0,sizeof(vis)); vis[1]=1;... 阅读全文
摘要:
题目大意:两串基因进行匹配(可能不一样长,不够就添加空格),任何两碱基之间以及碱基和空格匹配时所得分数已给出,求可以达到的最大分值。动态规划,两串基因存放在a,b数组中,用ans[ i ][ j ]表示a中前 i 个碱基和b中前 j 个碱基配对时的最大分数,则状态转移方程可以写为:ans[i][j]=max( ans[ i-1 ][ j-1 ] + w[ a[i] ][ b[j] ], ans[ i ][ j-1 ] + w[ 5 ][ b[j] ], ans[ i-1 ][ j ]+ w[ a[i] ][ 5 ] ),w数组存放碱基配对时的分数其中空格在第五列和第五行,该方程的意思为:对于a 阅读全文
摘要:
题目大意:对于图中节点要从起点走向终点,而且能从A节点走向B节点的条件是在B点存在一条到终点的路径,且这条路径的长度小于任何从A节点通往终点路径的长度,求共有几种走法。对于图中限制条件,其实只要判断从B到终点的最短路径是否小于从A点到终点的最小距离,若小于,则可以,否则不可以。经过这样转化后,题目将十分明显,深搜即可,但发现图中节点十分多,最多能达到1000个,所以深搜过程中要用记忆化搜索。#include #include #define INF 2000000 int map[1010][1010],n,m;int low[1010],s[1010];//low存放最短路径,s为标志数组, 阅读全文
摘要:
题目大意:在一个网格上会出现一些火星人,需要消灭他们,因此要在某些行(或列)安装激光枪,并且该激光枪只能杀死该行(或列)的火星人,在某列(或行)安装一个激光枪会产生花费,总的费用为这些费用的乘积,求把所有火星人都杀死的最小总花费。 相当于选一些行或列覆盖所有图中的火星人顶点,若把火星人视为边,行和列视为顶点,则可以这样构图:引入源汇s,t,对每个行节点,连接s与行节点,容量为在该行建立激光器的费用,连接列节点与汇点t,容量为在该列建立激光器的费用,若在原网格中点(i,j)上有一个火星人,则连接i,j,容量为无穷大INF,则最小割容量即为最小费用。 下面简述一下原因,将原图建立成二分图后,对于. 阅读全文
摘要:
题目大意:秦始皇修路,要求n个城市连通,然后有一个人可以帮忙修一条不花费的路,这个人希望这条路连接的两个城市的人数总和尽量大,所以要求这条魔法路连接的两个城市人数总和除以秦始皇需要修的路的花费这个值最大。 和求次小生成树的代码很类似,先说一下思路,先求最小生成树,然后枚举每条边当做魔法路,则分子确定了(两个城市人数总和),则只需修建其他路花费最小即可,①若该魔法路是最小生成树里的,则直接去掉即可,②若不是最小生成树里的,则添加魔法路后形成了一个环,只需将环上属于最小生成树的边中最大的那条去掉即可。 然后说明一下为什么其他边必须是最小生成树里的,除魔法路若有不属于mst的边,则把它去掉形成两个. 阅读全文