【BZOJ1001】【BJOI2006】狼抓兔子
2012-10-11 21:50
253 查看
BZOJ找虐记。
这道题..一看就是最小割,关键是裸做显然超时,
那么我们该怎么做呢?
Link:http://wenku.baidu.com/view/b31cc3d6c1c708a1284a447e.html 两级相通————浅析最大最小定理在信息学竞赛中的应用 By 周冬
这个给出了关于平面图最小割转化为最短路的详细过程及证明
既然最短路,那么DJ+堆就可以到O(nlogn)了,Discuss的SPFA有人被卡有人没有
另外注意n = 1 和 m = 1 要Special Judge
题目里面倒是没有什么容易写错的。
就是开了个D数组来记每个点的对应数码...实在是懒得算了。这样子相当方便不觉得吗?不过可能会慢些就是。
ps:这大概是我AC最快的一次。三次过。第一次特判写错,第二次是空间开小了,三次就过了。
不过由于写的静态,而且为了方便写了SPFA而不是DJHeap,所以时间上其丑无比(4000ms,第一名155ms...哭瞎了)。当然代码也是。
还是把我UGLY的Code放上来...不想瞎眼的情Ctrl + W好了TAT
这道题..一看就是最小割,关键是裸做显然超时,
那么我们该怎么做呢?
Link:http://wenku.baidu.com/view/b31cc3d6c1c708a1284a447e.html 两级相通————浅析最大最小定理在信息学竞赛中的应用 By 周冬
这个给出了关于平面图最小割转化为最短路的详细过程及证明
既然最短路,那么DJ+堆就可以到O(nlogn)了,Discuss的SPFA有人被卡有人没有
另外注意n = 1 和 m = 1 要Special Judge
题目里面倒是没有什么容易写错的。
就是开了个D数组来记每个点的对应数码...实在是懒得算了。这样子相当方便不觉得吗?不过可能会慢些就是。
ps:这大概是我AC最快的一次。三次过。第一次特判写错,第二次是空间开小了,三次就过了。
不过由于写的静态,而且为了方便写了SPFA而不是DJHeap,所以时间上其丑无比(4000ms,第一名155ms...哭瞎了)。当然代码也是。
还是把我UGLY的Code放上来...不想瞎眼的情Ctrl + W好了TAT
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<climits> #define ot "%d" #ifdef WIN32 #define otl "%I64d" #else #define otl "%lld" #endif #define Max(t, a, b) ({t _ = (a), __ = (b); _ > __ ? _ : __;}) #define min(a, b) ({int _ = (a), __ = (b); _ < __ ? _ : __;}) #define swap(a, b) ({int _ = (a); (a) = (b); (b) = _;}) #define maxp 2020055 #define maxm 1005 using namespace std; int n, m, fin, dis[maxp], h[maxp], nt[maxp << 2], t[maxp << 2], v[maxp << 2], tot, d[2][maxm][maxm]; void link(int a, int b, int c) { t[++tot] = b; nt[tot] = h[a]; v[h[a] = tot] = c; t[++tot] = a; nt[tot] = h[b]; v[h[b] = tot] = c; } void termin(int k) { int s, ans = INT_MAX; for (int i = 1; i < k; i++) scanf(ot, &s), ans = min(s, ans); printf(ot, ans); exit(0); } void init() { //freopen("1.in", "r", stdin); //freopen("1.out", "w", stdout); scanf(ot ot, &n, &m); if (n == 1) termin(m); if (m == 1) termin(n); int t; fin = 0; for (int i = 1; i < n; ++i) for (int j = 1; j < m; ++j) d[0][i][j] = ++fin, d[1][i][j] = ++fin; for (int i = 1; i < n; ++i) d[0][i][0] = d[1][i][0] = fin + 1, d[0][i][m] = d[0][i][m] = 0; for (int i = 1; i < m; ++i) d[0] [i] = d[1] [i] = fin + 1, d[0][0][i] = d[1][0][i] = 0; tot = 0; ++fin; for (int i = 1; i <= n; ++i) for (int j = 1; j < m; ++j) { scanf(ot, &t); link(d[0][i - 1][j], d[1][i][j], t); } for (int i = 1; i < n; ++i) for (int j = 1; j <= m; ++j) { scanf(ot, &t), link(d[1][i][j - 1], d[0][i][j], t); } for (int i = 1; i < n; ++i) for (int j = 1; j < m; ++j) { scanf(ot, &t); link(d[0][i][j], d[1][i][j], t); } } bool iq[maxp]; int que[maxp + 1], head, tail; bool relax(int a, int b, int c) { if (dis[a] + c < dis[b]) { dis[b] = dis[a] + c; if (!iq[b]) return 1; else return 0; } return 0; } void spfa() { head = 0, tail = 1, que[1] = 0; dis[0] = 0; do { if (++head == maxp) head = 1; int p = que[head]; for (int e = h[p]; e; e = nt[e]) if (relax(p, t[e], v[e])) { if (++tail == maxp) tail = 1; iq[que[tail] = t[e]] = 1; } iq[p] = 0; } while (head != tail); } int main() { init(); memset(dis, 63, sizeof dis); spfa(); printf("%d", dis[fin]); return 0; }
相关文章推荐
- [BZOJ1001] [BJOI2006] 狼抓兔子
- [bzoj1001][BJOI2006]狼抓兔子——最大流转最短路,平面图
- bzoj 1001 BJOI2006 狼抓兔子 最小割
- 【BJOI2006】bzoj1001 狼抓兔子
- BZOJ1001 BJOI2006狼抓兔子(最小割+最短路)
- [BJOI2006][bzoj1001] 狼抓兔子 [最小割]
- 【BZOJ】【1001】 【BJOI2006】狼抓兔子
- [BJOI2006] [BZOJ1001] 狼抓兔子|最大流|最短路
- [BZOJ1001][BeiJing2006]狼抓兔子
- BZOJ 1001([BeiJing2006]狼抓兔子-最大流转对偶图最短路)
- bzoj 1001: [BeiJing2006]狼抓兔子(最小割)
- BZOJ 1001: [BeiJing2006]狼抓兔子
- BZOJ1001: [BeiJing2006]狼抓兔子 (最小割)
- BZOJ 1001: [BeiJing2006]狼抓兔子
- BZOJ 1001 [BeiJing2006]狼抓兔子
- 【bzoj1001】[BeiJing2006]狼抓兔子
- BZOJ1001: [BeiJing2006]狼抓兔子
- bzoj1001: [BeiJing2006]狼抓兔子
- [BZOJ]1001: [BeiJing2006]狼抓兔子
- BZOJ1001 [BeiJing2006]狼抓兔子