BZOJ1001: [BeiJing2006]狼抓兔子 (最小割)
2015-11-15 13:06
288 查看
传送门
题目大意:求给出图的最小割(……题目就是这个意思)。
明眼一看,这就是一个裸的最大流,可是被数据范围吓住了,有106个点,然后又有3∗106条边,对于网络流可怜的O(n2m)的时间复杂度来说,简直是怪兽……但之前有同学告诉我,这道题就是最大流,我就硬着头皮上了一个ISAP,光荣超时,然后去找题解(想不出来了……)发现了两种,一种是把每一个面当做一个点,然后做最短路,即得最小割的容量,另一种竟然还是硬上网络流……黄学长用的dinic只用了800ms,而我之前的ISAP却用了15000+ms这不科学啊。然后我尝试着预标号,然后再ISAP,竟然只要500ms,太神了……
以后一定记住,要先预处理一遍!
代码:
题目大意:求给出图的最小割(……题目就是这个意思)。
明眼一看,这就是一个裸的最大流,可是被数据范围吓住了,有106个点,然后又有3∗106条边,对于网络流可怜的O(n2m)的时间复杂度来说,简直是怪兽……但之前有同学告诉我,这道题就是最大流,我就硬着头皮上了一个ISAP,光荣超时,然后去找题解(想不出来了……)发现了两种,一种是把每一个面当做一个点,然后做最短路,即得最小割的容量,另一种竟然还是硬上网络流……黄学长用的dinic只用了800ms,而我之前的ISAP却用了15000+ms这不科学啊。然后我尝试着预标号,然后再ISAP,竟然只要500ms,太神了……
以后一定记住,要先预处理一遍!
代码:
/************************************************************** Problem: 1001 User: geng4512 Language: C++ Result: Accepted Time:552 ms Memory:87896 kb ****************************************************************/ #include<cstdio> #include<cstring> const int MAXN = 1001*1001; inline int min(int a, int b) {return a < b ? a : b;} int ecnt = -1; struct node { int v, w, nxt; }Edge[MAXN*6]; int Adj[MAXN], q[MAXN]; bool vis[MAXN]; void Addedge(int u, int v, int w) { node *t = &Edge[++ ecnt]; t->v = v; t->w = w; t->nxt = Adj[u]; Adj[u] = ecnt; t = &Edge[++ ecnt]; t->v = u; t->w = w; t->nxt = Adj[v]; Adj[v] = ecnt; } char c; inline void GET(int &n) { n = 0; do c = getchar(); while(c > '9' || c < '0'); while('0' <= c && c <= '9') {n=n*10+c-'0';c=getchar();} } int n, m, ans, S, T, d[MAXN], vd[MAXN], N; int aug(int u, int augco) { int dmin = N-1, augc = augco, delta; if(u == T) return augco; for(int i = Adj[u]; ~i; i = Edge[i].nxt) if(Edge[i].w > 0) { if(d[Edge[i].v]+1 == d[u]) { delta = min(augc, Edge[i].w); delta = aug(Edge[i].v, delta); Edge[i].w -= delta; Edge[i^1].w += delta; augc -= delta; if(d[S] >= N) return augco - augc; if(!augc) return augco; } if(dmin > d[Edge[i].v]) dmin = d[Edge[i].v]; } if(augco == augc) { -- vd[d[u]]; if(!vd[d[u]]) d[S] = N; d[u] = ++ dmin; ++ vd[dmin]; } return augco - augc; } void bfs() { int l = 0, r = 0, u; q[++ r] = T; vis[T] = 1; vd[0] ++; while(l < r) { u = q[++ l]; for(int i = Adj[u]; ~i; i = Edge[i].nxt) { if(vis[Edge[i].v]) continue; d[Edge[i].v] = d[u] + 1; ++ vd[d[u]+1]; vis[Edge[i].v] = 1; q[++r] = Edge[i].v; } } } void sap() { bfs(); while(d[S] < N) ans += aug(S, 0x7fffffff); } int main() { int w; memset(Adj, -1, sizeof Adj); GET(n); GET(m); for(int i = 0; i < n; ++ i) for(int j = 0; j < m-1; ++ j) { GET(w); Addedge(i*m+j, i*m+j+1, w); } for(int i = 0; i < n-1; ++ i) for(int j = 0; j < m; ++ j) { GET(w); Addedge(i*m+j, (i+1)*m+j, w); } for(int i = 0; i < n-1; ++ i) for(int j = 0; j < m-1; ++ j) { GET(w); Addedge(i*m+j, (i+1)*m+j+1, w); } T = n*m-1; N = n*m; sap(); printf("%d\n", ans); return 0; }
相关文章推荐
- Decode Ways
- android TypedArray Empty after obtainStyledAttributes
- Android版本检测升级
- BZOJ1001: [BeiJing2006]狼抓兔子 (最小割)
- 线程间通讯------生产者与消费者(JDK升级版)
- HTML 获取控件的值
- 继承,多态,重写,重载
- for,foreach遍历数组
- php面向对象--多态
- Java的接口和抽象类
- js常用方法集锦
- Oracle的某些例题以及答案
- 负载均衡项目实施中应该注意的事项
- JavaScript 练习(四)排序小程序
- 深入Mysql字符集设置
- 负载均衡实施应该因地制宜
- 谷歌再次延长 Chrome 浏览器对 XP 的支持期
- 为父母设计的一款手机
- 算数-集合
- Centos下Yum安装PHP5.5,5.6