博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[校内集训] 氵
阅读量:5032 次
发布时间:2019-06-12

本文共 1421 字,大约阅读时间需要 4 分钟。

题意

给一张网格图,每个格子有高度,假设边界之外的区域无限大且高度为0,向整个图灌氵,问到最后每个格子上氵柱的高度(氵往低处流)

思路

贪心:一个点可以存的氵量等于它到网格图外面的一条路径上最高的格子减去自己的高度

限制:上述路径最大值中应该选取最小的,因为如果选了一条最大值大的路径,氵就会从另一条最大值较小的路径流走

将相邻点之间连边,边权为两个格子高度的较大值,边界格子向根节点连边,边权为\(max(h,0)\),对于限制,跑出原图的最小生成树(即保证两点之间连通性的最短路径),对于贪心,从根出发到每个点即可得到上面说的最大值,\(ans[i][j]=maxx-h[i][j]\)

Code

#include
#define N 305#define Min(x,y) ((x)<(y) ? (x):(y))using namespace std;const int INF = 1000000000;int n,m,s,c,fa[N*N];int a[N][N],ans[N][N];int dox[4]={0,-1,0,1},doy[4]={1,0,-1,0};struct E {int u,v,w;} e[N*N*4];struct Edge{ int next,to,dis;}edge[N*N*2];int head[N*N],cnt;void add_edge(int from,int to,int dis){ edge[++cnt].next=head[from]; edge[cnt].to=to; edge[cnt].dis=dis; head[from]=cnt;}template
void read(T &x){ char c;int sign=1; while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48; while((c=getchar())>='0'&&c<='9') x=x*10+c-48; x*=sign;}int find(int x) {return x==fa[x] ? fa[x] : fa[x] = find(fa[x]);} int getid(int x,int y) {return (x-1)*m+y;}bool cmp(E a,E b) {return a.w
n||dy>m) e[++c]=(E){s,getid(i,j),max(a[i][j],0)}; else e[++c]=(E){getid(i,j),getid(dx,dy),max(a[i][j],a[dx][dy])}; } kruskal(); dfs(s,0,-INF); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) printf("%d ",ans[i][j]); printf("\n"); } return 0;}

转载于:https://www.cnblogs.com/Chtholly/p/11435029.html

你可能感兴趣的文章
Android开发学习之路-图片颜色获取器开发(1)
查看>>
StackExchange.Redis 官方文档(一) Basics
查看>>
nupkg 之破解 nodejs+electron-packager 打包exe的解包
查看>>
Objective-C 使用 C++类
查看>>
浅谈之高级查询over(partition by)
查看>>
Notes: CRM Analytics–BI from a CRM perspective (2)
查看>>
graphite custom functions
查看>>
列出所有的属性键
查看>>
js获取请求地址后面带的参数
查看>>
[原创]使用java批量修改文件编码(ANSI-->UTF-8)
查看>>
设计模式のCompositePattern(组合模式)----结构模式
查看>>
二进制集合枚举子集
查看>>
磁盘管理
查看>>
SAS学习经验总结分享:篇二—input语句
查看>>
UIImage与UIColor互转
查看>>
RotateAnimation详解
查看>>
系统管理玩玩Windows Azure
查看>>
c#匿名方法
查看>>
如何判断链表是否有环
查看>>
【小程序】缓存
查看>>