HDU6214(最小割SAP模板题)
来源:互联网 发布:二维码生成算法 c语言 编辑:程序博客网 时间:2024/06/05 23:59
这个题就是求最小割边数目,太菜了,这个题交的时候没法看是wa还是TLE,结果连交三发,全都是红,我有些怀疑TLE,但是又不敢肯定,(MDZZ,200点,1000边稠密图还用dinic),当时也蒙了,我就盯着每秒刷新看了11页,看的眼睛都花了,终于找到tle。果断上SAP,终于是过了。MDZZ,这周智障的格外厉害。
关于最小割边的边数量,我们用E代表最大边数量。
每条边的流量记为w,我们存图时,存入的为(w*(E+1)+1)
为什么呢?
我们可以把最后一个1看成每条边的标记,这标记最后取,这样只有着天边全取时才会把这个1加入到最大流中,代表这条增广路中限制流量的那条边取到了,而这条边恰恰是最小割的组成部分。
这样最大流为ans/(E+1),最小割边数量为ans%(E+1)
code:
#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<iostream>#include<string>#include <set>#include<time.h>//a&3==a%4using namespace std;#define ll long long#define intt long long#define mem(a) memset(a,0,sizeof(a))const double eps=1e-8;const int MAXN = 1010;//点数的最大值+10const int MAXM = 10010;//边数的最大值+10const int INF = 0x3f3f3f3f;struct Edge{ int to,next,cap,flow;}edge[MAXM];int tol;int head[MAXN];int gap[MAXN],dep[MAXN],cur[MAXN];void init(){ tol = 0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int w,int rw = 0){ edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;}int Q[MAXN];void BFS(int start,int end){ memset(dep,-1,sizeof(dep)); memset(gap,0,sizeof(gap)); gap[0] = 1; int front = 0, rear = 0; dep[end] = 0; Q[rear++] = end; while(front != rear) { int u = Q[front++]; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(dep[v] != -1)continue; Q[rear++] = v; dep[v] = dep[u] + 1; gap[dep[v]]++; } }}int S[MAXN];ll sap(int start,int end,int N){ BFS(start,end); memcpy(cur,head,sizeof(head)); int top = 0; int u = start; ll ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; int inser; for(int i = 0;i < top;i++) if(Min > edge[S[i]].cap - edge[S[i]].flow) { Min = edge[S[i]].cap - edge[S[i]].flow; inser = i; } for(int i = 0;i < top;i++) { edge[S[i]].flow += Min; edge[S[i]^1].flow -= Min; } ans += (ll)(Min); top = inser; u = edge[S[top]^1].to; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = i; break; } } if(flag) { S[top++] = cur[u]; u = v; continue; } int Min = N; for(int i = head[u]; i != -1; i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min + 1; gap[dep[u]]++; if(u != start)u = edge[S[--top]^1].to; } return ans;}int main(){ int kase; scanf("%d",&kase); while(kase--) { init(); int n,m,s,t; cin>>n>>m>>s>>t; for(int i=0;i<m;i++) { int u,v,w; cin>>u>>v>>w; addedge(u,v,w*MAXM+1); } ll res=sap(s,t,n); res=res%(ll)(MAXM); cout<<res<<endl; } return 0;}
阅读全文
0 0
- HDU6214(最小割SAP模板题)
- hdu6214-最小割集中边数最少
- HDU6214 Smallest Minimum Cut【最小割-最小边数】
- hdu6214-最小割边数&最大流最小割-Smallest Minimum Cut
- HDU6214 Smallest Minimum Cut 【最大流求最小割边】
- hdu6214(求最小割最少边数)
- poj 3469 最小割模板sap+gap+弧优化
- poj 3469 最大流-最小割 SAP算法模板
- hdu6214—Smallest Minimum Cut(最小割的最少割边)
- 【HDU】3452 Bonsai 最小割模板题
- POJ2914 Minimum Cut(最小割模板题)
- hdu 3002 全局最小割模板题
- (最小割模板)
- 全局最小割模板
- 最小割模板
- 全局最小割模板
- 【2017青岛网络赛】1009 Smallest Minimum Cut hdu6214 最小割 最大流模版
- HDU6214 Smallest Minimum Cut 最小割/最少边 [2017 ACM/ICPC Asia Regional Qingdao Online]
- mysql 复习
- As修改项目名,模块名,包名
- Serlvet3.0 注解 浅析
- hdu 1262 寻找素数
- [effectiv c++]条款33:避免遮掩继承而来的名称(重载,重写,重定义)
- HDU6214(最小割SAP模板题)
- 链家校招面试(c++开发)
- 为QLabel添加鼠标事件
- HDU 5547 Sudoku(dfs+模拟+状态判断)
- 闭包的简单理解
- 从零开始前端学习[11]:控制文本显示的样式属性
- 敏捷开发--概念及其应用
- 2017-9-19考试总结
- java数据库编程--事务处理