图论模板集合
2014-04-26 19:58
246 查看
二分图模板
匈牙利算法 时间复杂度O(n^3)
Hopcroft-Karp算法 时间复杂度O(n^0.5*e)
讲解参照
最大流模板
Edmonds-Karp算法 时间复杂度O(n*e^2)
dinic算法 O(n*n*m)
效率相对于上面快了很多
匈牙利算法 时间复杂度O(n^3)
int n1,n2,k; //n1,n2为二分图的顶点集,其中x∈n1,y∈n2 int map ,vis ,link ; //link记录n2中的点y在n1中所匹配的x点的编号 int find(int x) { int i; for(i=1;i<=n2;i++) { if(map[x][i]&&!vis[i])//x->i有边,且节点i未被搜索 { vis[i]=1;//标记节点已被搜索 //如果i不属于前一个匹配M或被i匹配到的节点可以寻找到增广路 if(link[i]==0||find(link[i])) { link[i]=x;//更新 return 1;//匹配成功 } } } return 0; }
Hopcroft-Karp算法 时间复杂度O(n^0.5*e)
讲解参照
vector<int>ed[N]; int xlink[N],ylink[N];/*xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。*/ bool vis[N]; //寻找增广路的标记数组 int dx[N],dy[N];/*dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号*/
int dis,n;
void init() { memset(xlink,-1,sizeof(xlink)); memset(ylink,-1,sizeof(ylink)); } int bfs() { memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); int i; queue<int>q; dis = INF; for(i = 1 ; i <= n;i++) if(xlink[i]==-1) { q.push(i); dx[i] = 0; } while(!q.empty()) { int u = q.front(); q.pop(); if(dx[u]>dis) break; for(i = 0 ;i < ed[u].size() ; i++) { int v = ed[u][i]; if(dy[v]==-1) { dy[v] = dx[u]+1; if(ylink[v]==-1) dis = dy[v]; else { dx[ylink[v]] = dy[v]+1; q.push(ylink[v]); } } } } return dis!=INF; } int find(int u) { int i; for(i = 0;i < ed[u].size() ; i++) { int v = ed[u][i]; if(vis[v]||dy[v]!=dx[u]+1) continue; vis[v] = 1; if(ylink[v] != -1&&dy[v]==dis) continue; if(ylink[v]==-1||find(ylink[v])) { ylink[v] = u; xlink[u] = v; return 1; } } return 0; } int hk() { int ans = 0,i; while(bfs()) { memset(vis,0,sizeof(vis)); for(i = 1 ; i <= n ;i++) { if(xlink[i]==-1) ans+=find(i); } } return ans; }
最大流模板
Edmonds-Karp算法 时间复杂度O(n*e^2)
int path ,flow ,gh ,st,en; int bfs() { int i; memset(path,-1,sizeof(path)); for(i = 1 ; i <= en ; i++) flow[i] = INF; queue<int>q; q.push(1); while(!q.empty()) { int tk = q.front(); q.pop(); if(tk==en) break; for(i = 1 ; i <= en ; i++) { if(path[i]==-1&&gh[tk][i]) { path[i] = tk; flow[i] = min(flow[tk],gh[tk][i]); q.push(i); } } } if(path[en]==-1) return -1; return flow[en]; } int km() { int now,pre,sum=0,k; while((k=bfs())!=-1) { sum+=k; now = en; while(now!=st) { pre = path[now]; gh[pre][now]-=k; gh[now][pre]+=k; now = pre; } } return sum; }
dinic算法 O(n*n*m)
效率相对于上面快了很多
#define INF 0x3f3f3f const int N = 415; #define M 160015 struct node { int u,v,next; int w; } edge[M<<1]; int head ,t,vis ,pp ,dis ; int o ; int st,en; int x ,f ; void init() { t=0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { edge[t].u = u; edge[t].v = v; edge[t].w = w; edge[t].next = head[u]; head[u] = t++; edge[t].u = v; edge[t].v = u; edge[t].w = 0; edge[t].next = head[v]; head[v] = t++; } int bfs() { int i,u; int w; memset(dis,-1,sizeof(dis)); queue<int>q; q.push(st); dis[st] = 0; while(!q.empty()) { u = q.front(); q.pop(); for(i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v; w = edge[i].w; if(dis[v]<0&&w>0) { dis[v] = dis[u]+1; q.push(v); } } } if(dis[en]>0) return 1; return 0; } int dfs(int u,int te) { int i; int s; if(u==en) return te; for(i = head[u] ; i != -1 ; i = edge[i].next) { int v = edge[i].v; int w = edge[i].w; if(w>0&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w)))) { edge[i].w-=s; edge[i^1].w+=s; return s; } } dis[u] = -1; return 0; } int dinic() { int flow = 0; int res; while(bfs()) { while(res = dfs(st,INF)) flow+=res; } return flow; }
相关文章推荐
- 图论模板集合
- 集合的模拟实现(函数模板)
- 免费的Bootstrap管理后台模板集合
- 算法模板之图论
- 图论集合
- 【笔记+模板】图论中的树
- 【模板】其他图论
- 浅谈计算几何的模板集合
- 【计算集合模板+几个典型的题目】2016 湖南acm省赛
- 模板整理——图论·最小生成树·Kruskal
- [导入]免费css布局和模板集合
- 简单图论(Dijkstra模板) HDU1874:畅通工程
- 图论--有向图强连通分量的标记及缩点模板
- 【算法模板】图论
- 移动手机版网页模板集合
- POJ 1144 Network 图论 求割点模板
- 测试用例模板集合
- java常用IO流集合用法模板
- [置顶] NOIP常考模板粗略集合包
- 防2B && 图论模板 && 7788