BZOJ-1001 狼抓兔子
这道题是最小割,但是由于图的特殊性及数据范围,这道题只能用最短路做。
Dijkstra+堆,112ms。
【顺便说一下BZOJ的尿性,我是MLE了却硬显示是TLE,害的我。。。】
#include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <fstream> #include <iostream> #include <queue> #define rep(i, l, r) for(int i=l; i<=r; i++) #define N 1009 #define MAX 2147483647 #define clr(x, c) memset(x, c, sizeof(x)) using namespace std; int read() { int x=0, f=1; char ch=getchar(); while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } struct edge{int y, n, z;} e[N*N*20]; int fir[N*N*2], en; struct data { int x, d; data(int a, int b) : x(a), d(b) {} bool operator < (const data &k) const { return d>k.d; } }; int n, m, g[3][N][N], l[N][N], k, d[N*N*2]; inline void Add(int x, int y, int z) { en++, e[en].y=y, e[en].z=z, e[en].n=fir[x], fir[x]=en; en++, e[en].y=x, e[en].z=z, e[en].n=fir[y], fir[y]=en; } int main() { n=read(); m=read(); rep(i, 1, n) rep(j, 1, m-1) g[1][i][j]=read(); rep(i, 1, n-1) rep(j, 1, m) g[2][i][j]=read(); rep(i, 1, n-1) rep(j, 1, m-1) g[0][i][j]=read(); k=0; rep(i, 1, n-1) rep(j, 1, m-1) l[i][j]=(++k)*2; k=k*2+1; rep(i, 2, n-1) rep(j, 1, m-1) Add(l[i-1][j]-1, l[i][j], g[1][i][j]); rep(i, 1, n-1) rep(j, 2, m-1) Add(l[i][j-1], l[i][j]-1, g[2][i][j]); rep(i, 1, n-1) rep(j, 1, m-1) Add(l[i][j]-1, l[i][j], g[0][i][j]); rep(i, 1, n-1) Add(0, l[i][1]-1, g[2][i][1]); rep(i, 1, m-1) Add(0, l[n-1][i]-1, g[1][n][i]); rep(i, 1, m-1) Add(l[1][i], k, g[1][1][i]); rep(i, 1, n-1) Add(l[i][m-1], k, g[2][i][m]); rep(i, 0, k) d[i]=MAX; priority_queue <data> q; q.push(data(0, 0)); while (d[k]==MAX) { data a=q.top(); int x=a.x, o=fir[x], y=e[o].y; q.pop(); if (d[x]!=MAX) continue; else d[x]=a.d; while (o) { if (d[y]==MAX) q.push(data(y, d[x]+e[o].z)); o=e[o].n, y=e[o].y; } } printf("%d\n", d[k]); return 0; }