BZOJ1736: [Usaco2005 jan]The Wedding Juicer 婚宴的榨汁机
给一个n*m的榨汁机的内部结构,即n*m块柱子的高度,问这个榨汁机能装多少水。n,m<=300。
突然不会搜索??????
对每个点记外界能到达他的最大高度,每次选一个这个通往外界的最大高度最小的点来算他的贡献:如果到达一个未访问过并且高度比他通往外界最大高度要小的点就可以流。因为是从小到大考虑,且一开始把最外圈都设为不能访问,所以计算答案时不会出现流出去的情况。
1 #include<cstring> 2 #include<cstdlib> 3 #include<cstdio> 4 //#include<assert.h> 5 //#include<time.h> 6 #include<math.h> 7 #include<queue> 8 #include<algorithm> 9 //#include<iostream> 10 using namespace std; 11 12 bool isdigit(char c) {return c>='0' && c<='9';} 13 int qread() 14 { 15 char c;int s=0,f=1;while (!isdigit(c=getchar())) f=(c=='-'?-1:1); 16 do s=s*10+c-'0'; while (isdigit(c=getchar())); return s*f; 17 } 18 19 int n,m; 20 #define maxn 311 21 int mp[maxn][maxn];bool vis[maxn][maxn]; 22 const int dx[]={0,0,1,-1},dy[]={1,-1,0,0}; 23 #define LL long long 24 struct qnode 25 { 26 int v,x,y; 27 bool operator > (const qnode &b) const {return v>b.v;} 28 }; 29 priority_queue<qnode,vector<qnode>,greater<qnode> > q; 30 LL work() 31 { 32 LL ans=0; 33 vis[1][1]=vis[1][m]=vis[n][1]=vis[n][m]=1; 34 for (int i=2;i<n;i++) 35 q.push((qnode){mp[i][1],i,1}),q.push((qnode){mp[i][m],i,m}),vis[i][1]=vis[i][m]=1; 36 for (int i=2;i<m;i++) 37 q.push((qnode){mp[1][i],1,i}),q.push((qnode){mp[n][i],n,i}),vis[1][i]=vis[n][i]=1; 38 while (!q.empty()) 39 { 40 const int x=q.top().x,y=q.top().y,h=q.top().v;q.pop(); 41 for (int i=0;i<4;i++) 42 { 43 int xx=x+dx[i],yy=y+dy[i]; 44 if (xx<1 || xx>n || yy<1 || yy>m || vis[xx][yy]) continue; 45 vis[xx][yy]=1; 46 if (mp[xx][yy]<h) 47 { 48 ans+=h-mp[xx][yy]; 49 mp[xx][yy]=h; 50 } 51 q.push((qnode){mp[xx][yy],xx,yy}); 52 } 53 } 54 return ans; 55 } 56 int main() 57 { 58 m=qread(),n=qread(); 59 for (int i=1;i<=n;i++) 60 for (int j=1;j<=m;j++) 61 mp[i][j]=qread(); 62 printf("%lld\n",work()); 63 return 0; 64 }