18-1-30~2~5一周算法总结(DP,二分图,最小生成树)
2018-02-05 16:57
417 查看
30
DP(最长上升子序列和lcs)
摸了
1
DP(01背包和完全背包)
01背包
3
二分图
2点,一个是区分是否二分图,一个是算二分图的最多匹配数。
是否二分可以很简单的用染色来判断。bfs遍历。
算匹配数用到匈牙利算法。核心代码如下。
邻接矩阵
下次再补
PS:还有需要注意的一些细节
1最大不相关个数=总个数-最大匹配个数
2如果没有专门给你区分x来着左,y来自右,那么可以在构建的时候line[x][y]=1,line[y][x]=1,但是这样的话
最大匹配=match()/2;
3其实给我们一个有向图,在做与1内容相关的题目的时候,我们可以近似的看成是无向图,不过是出发点是左,
终点是右,来计算。(也不是很懂,但是可以做)poj 1422
4最大匹配个数=(覆盖图的)最小顶点个数
5
最小生成树
需要并查集。
其次基本思想是套用kruskal算法,将边的花费保存,并按从小到大打排序,依次取出边,如果边的2个端点没有通路,则把这2个端点用这条边连起来。
代码
[b]非课程相关
突然知道的,
![](https://oscdn.geek-share.com/Uploads/Images/Content/202012/05/2d62feee0ffb2ec462f32a371c3d26a5)
ll超过范围会自动取模啊,ull也是!
DP(最长上升子序列和lcs)
摸了
1
DP(01背包和完全背包)
01背包
for(int i=1;i<=n;i++){ for(int j=k;j>=w[i];j--){ dp[j]=max(dp[j-w[i]]+v[i],dp[j]);//维护对于第i个物品,不放的时候的最大值和放了之后空间减少w[i]的最大值 } }完全背包和01背包基本一致,唯一的区别是从01是逆推但是完全是顺推(顺推就可以在已经放了本物品的基础上再次放)
for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++){ if(j>=w[i]){ dp[j]=min(dp[j],dp[j-w[i]]+v[i]); } } }对于那种可以在最后的空间插入更大的值的问题,可以一上来就把空间j的大小减x来达到。
3
二分图
2点,一个是区分是否二分图,一个是算二分图的最多匹配数。
是否二分可以很简单的用染色来判断。bfs遍历。
算匹配数用到匈牙利算法。核心代码如下。
邻接矩阵
int n,m; int line[1000+5][1000+5],used[1000+5],nxt[1000+5] ; bool Find(int x){ for(int i=1;i<=m;i++){ if(line[x][i]&&!used[i]){ used[i]=1; if(nxt[i]==0||Find(nxt[i])){ nxt[i]=x; return true; } } } return false; } int match(){ int all=0; for(int i=1;i<=n;i++){ mem(used,0); if(Find(i)) all++; } return all; }邻接表
下次再补
PS:还有需要注意的一些细节
1最大不相关个数=总个数-最大匹配个数
2如果没有专门给你区分x来着左,y来自右,那么可以在构建的时候line[x][y]=1,line[y][x]=1,但是这样的话
最大匹配=match()/2;
3其实给我们一个有向图,在做与1内容相关的题目的时候,我们可以近似的看成是无向图,不过是出发点是左,
终点是右,来计算。(也不是很懂,但是可以做)poj 1422
4最大匹配个数=(覆盖图的)最小顶点个数
5
最小生成树
需要并查集。
其次基本思想是套用kruskal算法,将边的花费保存,并按从小到大打排序,依次取出边,如果边的2个端点没有通路,则把这2个端点用这条边连起来。
代码
const int maxn=1e5+5; int f[maxn]; struct edge{ int x,y,cost; } e[10005]; //int rank[maxn]; void init(){//初始化// for(int i=1;i<maxn;i++){ f[i]=i; // rank[i]=0; } } int find(int x){//查找并优化到这条链上的所以结点都和根直接相连// return f[x]==x?x:f[x]=find(f[x]); } void un(int x,int y){//连点// 未用rank优化,取消掉/则转变为rank优化// int a=find(x); int b=find(y); if(a!=b){ // if(rank[a]>rank) f[b]=a; /* else{ f[a]=b; if(rank[a]==rank[b]) rank[a]++; }*/ } } bool cmp(edge e1,edge e2){ return e1.cost<e2.cost; } int kruskal(){ init(); sort(e,e+m,cmp); int all=0; for(int i=0;i<m;i++){ int x=e[i].x; int y=e[i].y; if(find(x)==find(y)) continue; un(x,y); all+=e[i].cost; } return all; }PS:我这里是返回了最小生成树的边的长度。
[b]非课程相关
突然知道的,
ll超过范围会自动取模啊,ull也是!
相关文章推荐
- 18-1-22~28一周算法总结(DP,并查集)
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- 最小生成树相关算法总结
- 最小生成树算法总结
- PAT 数据结构 06-图6. 公路村村通(30)Prim最小生成树算法
- 曼哈顿距离最小生成树与莫队算法(总结)
- 最小生成树的两种算法总结(克鲁斯塔尔,prim)
- 最小生成树&最短路基础算法总结
- 图论总结,查分约束系统讲解,最短路,最小生成树,二分图
- POJ 1463 Strategic game (二分图最小覆盖点(匈牙利算法) 或 树形DP)
- 7-9 公路村村通(30 分) 最小生成树 需要再深入研究算法*******************
- 邻接表存储 - Kruskal最小生成树算法
- BZOJ 1937: [Shoi2004]Mst 最小生成树 [二分图最大权匹配]
- 十大基础有用算法之迪杰斯特拉算法、最小生成树和搜索算法
- 浅谈最小生成树的算法思路(一)Prim算法
- 最小生成树算法汇总
- 算法导论 | 第23章 最小生成树
- Prim最小生成树算法
- hdu 1863 畅通工程 (最小生成树kruskal 算法)
- 算法:最小生成树