zoukankan      html  css  js  c++  java
  • 【六省2017】寿司餐厅

    我发现我学的最大权闭合子图一直是假的,自闭了。

    最大权闭合子图:选一点之前一定要选这个点的后继

    $S$连正,负连$T$,边权为点权的绝对值。

    题面

    https://loj.ac/problem/2146

    题解

    注意离散化之后的二分答案,$n$应该是压缩后的$n$,即$tot$。

    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 10050
    #define INF 1000000007
    #define S 0
    #define T (cc+1)
    #define LL long long
    #define ri register int
    using namespace std;
    
    int n,m,tot,cc;
    int a[145],d[145][145],dct[145];
    int bh[145][145];
    bool vis[145];
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    struct graph {
      vector<int> ed[N],w,to;
      int d[N],cur[N],p[N];
      void add_edge(int u,int v,int tw) {
        to.push_back(v); w.push_back(tw); ed[u].push_back(to.size()-1);
        to.push_back(u); w.push_back(0);  ed[v].push_back(to.size()-1);
      }
      bool bfs() {
        queue<int> q;
        memset(d,0x3f,sizeof(d));
        d[S]=0; q.push(S);
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<ed[x].size();i++) {
            int e=ed[x][i];
            if (d[x]+1<d[to[e]] && w[e]) {
              d[to[e]]=d[x]+1;
              q.push(to[e]);
            }
          }
        }
        return d[T]<INF;
      }
      int dfs(int x,int limit) {
        if (x==T || limit==0) return limit;
        int sum=0; 
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (w[e] && d[x]+1==d[to[e]]) {
            int f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            sum+=f; limit-=f; 
            w[e]-=f; w[1^e]+=f;
            if (!limit) return sum;
          }
        }
        return sum;
      }
      int dinic() {
        int ret=0;
        while (bfs()) {
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF);
        }
        return ret;
      }
    } G;
    
    int main() {
      n=read(); m=read();
      for (ri i=1;i<=n;i++) a[i]=read();
      int sum=0;
      for (ri i=1;i<=n;i++) {
        for (ri j=i;j<=n;j++) {
          d[i][j]=read();
          if (d[i][j]>0) sum+=d[i][j];
        }
      }
      for (ri i=1;i<=n;i++) dct[i]=a[i];
      sort(dct+1,dct+n+1);
      tot=unique(dct+1,dct+n+1)-dct-1;
      cc=tot;
      for (ri i=1;i<=n;i++) bh[i][i]=++cc;
      for (ri i=1;i<n;i++)
        for (ri j=i+1;j<=n;j++) bh[i][j]=++cc;
      for (ri i=1;i<=n;i++) {
        int x=lower_bound(dct+1,dct+tot+1,a[i])-dct;
        if (!vis[x]) {
          vis[x]=1;
          if (m) G.add_edge(x,T,a[i]*a[i]);
        }
        G.add_edge(bh[i][i],T,a[i]);
        G.add_edge(bh[i][i],x,INF);
      }
      for (ri i=1;i<=n;i++) 
        for (ri j=i;j<=n;j++) if (d[i][j]>0) G.add_edge(S,bh[i][j],d[i][j]); else G.add_edge(bh[i][j],T,-d[i][j]);
      for (ri i=1;i<n;i++)
        for (ri j=i+1;j<=n;j++) {
          G.add_edge(bh[i][j],bh[i+1][j],INF);
          G.add_edge(bh[i][j],bh[i][j-1],INF);
        }
      cout<<sum-G.dinic()<<endl;
    }
  • 相关阅读:
    记一次线上OOM问题分析与解决
    理解JAVA内存模型
    SpringBoot+Shiro+JPA+LayUI的后台管理系统
    学会使用BeanUtils,提高你的开发效率
    一篇文章教你快速上手接口管理工具swagger
    js 多维数组转一维数组(根据字段展示)
    记一次阿里云服务器中部署egg遇到的问题 (docker vim)
    react 封装tab组件
    js 添加 好玩的注释
    js 下载文件流
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11291177.html
Copyright © 2011-2022 走看看