• [POI2018]Powódź


    题目大意:
      一个$n imes m(nmle5 imes10^5)$的网格图,每个格子间有一个给定高度的挡板,每个格子的水位是$0sim h(hle10^9)$之间的一个整数。问总共有多少种可能的水位情况。

    思路:
      建立Kruskal重构树,实点代表原图中的格点,虚点代表若干个格点水位越过挡板进行合并后形成的新连通块。求出每个点所代表连通块的水位最大值$max[i]$和最小值$min[i]$,根结点的$max$值为$h$。进行树形DP。转移方程$f[i]=f[ch[i][0]] imes f[ch[i][1]]+max[i]-min[i]+1$。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<algorithm>
     4 #include<sys/mman.h>
     5 #include<sys/stat.h>
     6 typedef long long int64;
     7 class MMapInput {
     8     private:
     9         char *buf,*p;
    10         int size;
    11     public:
    12         MMapInput() {
    13             register int fd=fileno(stdin);
    14             struct stat sb;
    15             fstat(fd,&sb);
    16             size=sb.st_size;
    17             buf=reinterpret_cast<char*>(mmap(0,size,PROT_READ,MAP_PRIVATE,fileno(stdin),0));
    18             p=buf;
    19         }
    20         char getchar() {
    21             return (p==buf+size||*p==EOF)?EOF:*p++;
    22         }
    23 };
    24 MMapInput mmi;
    25 inline int getint() {
    26     register char ch;
    27     while(!isdigit(ch=mmi.getchar()));
    28     register int x=ch^'0';
    29     while(isdigit(ch=mmi.getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    30     return x;
    31 }
    32 const int N=1e6,mod=1e9+7;
    33 int n,m,h,cnt,tot,max[N],min[N],ch[N][2],f[N];
    34 struct Edge {
    35     int u,v,w;
    36     bool operator < (const Edge &another) const {
    37         return w<another.w;
    38     }
    39 };
    40 Edge e[N];
    41 inline int id(const int &x,const int &y) {
    42     return x*m+y+1;
    43 }
    44 struct DisjointSet {
    45     int anc[N];
    46     DisjointSet() {
    47         for(register int i=0;i<N;i++) anc[i]=i;
    48     }
    49     int find(const int &x) {
    50         return x==anc[x]?x:anc[x]=find(anc[x]);
    51     }
    52     void merge(const int &x,const int &y) {
    53         anc[find(x)]=find(y);
    54     }
    55     bool same(const int &x,const int &y) {
    56         return find(x)==find(y);
    57     }
    58 };
    59 DisjointSet s;
    60 inline void kruskal() {
    61     tot=n*m;
    62     std::sort(&e[0],&e[cnt]);
    63     for(register int i=0;i<cnt;i++) {
    64         const int &u=e[i].u,&v=e[i].v,&w=e[i].w;
    65         if(!s.same(u,v)) {
    66             min[++tot]=w+1;
    67             max[s.find(u)]=max[s.find(v)]=w;
    68             ch[tot][0]=s.find(u);
    69             ch[tot][1]=s.find(v);
    70             s.merge(u,tot);
    71             s.merge(v,tot);
    72         }
    73     }
    74 }
    75 int main() {
    76     n=getint(),m=getint(),max[n*m*2-1]=getint();
    77     for(register int i=0;i<n;i++) {
    78         for(register int j=1;j<m;j++) {
    79             e[cnt++]=(Edge){id(i,j-1),id(i,j),getint()};
    80         }
    81     }
    82     for(register int i=1;i<n;i++) {
    83         for(register int j=0;j<m;j++) {
    84             e[cnt++]=(Edge){id(i-1,j),id(i,j),getint()};
    85         }
    86     }
    87     kruskal();
    88     for(register int i=1;i<=tot;i++) {
    89         f[i]=((int64)f[ch[i][0]]*f[ch[i][1]]+max[i]-min[i]+1)%mod;
    90     }
    91     printf("%d
    ",f[tot]);
    92     return 0;
    93 }
  • 相关阅读:
    [Algorithm] Flowerbox: Dynamic programming
    [CSS 3] Overflow & sticky problem
    [Algorithm] Bottom-up Dynamic programming approch
    高频交易的理论基石 —— 市场微观结构
    固态硬盘windows10安装笔记
    本土高频量化交易大败局:市场所有参与者共同作用的恶性循环
    CER.LIVE Report: Top 25 Decentralized Exchanges by Cybersecurity Score
    如何判断两条轨迹(或曲线)的相似度?
    皮尔逊相关系数实现相似K线及其性能优化
    视频:高盛王牌交易员揭露交易的真相
  • 原文地址:https://www.cnblogs.com/skylee03/p/8711067.html
Copyright © 2020-2023  润新知