zoukankan      html  css  js  c++  java
  • 【SNOI2019】通信

    题面

    https://www.luogu.org/problem/P5331

    题解

    莫名的感觉像餐巾计划问题。

    一开始和餐巾错的一样(两次在一个坑里面跌倒了。。。。)后来安装餐巾的思路改一改就对了。

    $orz yyb$

    $orz zsy$

    分治连边。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #define N 65000
    #define ri register int
    #define LL long long
    #define S 0
    #define T (2*n+1)
    #define INF 1000000007
    using namespace std;
    
    int n,w,cc;
    int id[N],t[N],a[N];
    
    struct graph {
      vector<int> to,w,len,ed[N];
      int vis[N],cur[N],dis[N];
      void add_edge(int u,int v,int tw,int tl) {
        w.push_back(tw); len.push_back(tl); to.push_back(v); ed[u].push_back(w.size()-1);
        w.push_back(0); len.push_back(-tl); to.push_back(u); ed[v].push_back(w.size()-1);
      }
      bool spfa() {
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<int> q;
        dis[S]=0; q.push(S); vis[S]=1;
        while (!q.empty()) {
          int x=q.front(); q.pop();
          for (ri i=0;i<ed[x].size();i++) {
            int e=ed[x][i];
            if (w[e] && dis[to[e]]>dis[x]+len[e]) {
              dis[to[e]]=dis[x]+len[e];
              if (!vis[to[e]]) {
                vis[to[e]]=1;
                q.push(to[e]);
              }
            }
          }
          vis[x]=0;
        }
        return dis[T]<INF;
      }
      int dfs(int x,int limit) {
        if (x==T || !limit) return limit;
        vis[x]=1; int sum=0;
        for (ri &i=cur[x];i<ed[x].size();i++) {
          int e=ed[x][i];
          if (w[e] && dis[to[e]]==dis[x]+len[e] && !vis[to[e]]) {
            int f=dfs(to[e],min(limit,w[e]));
            if (!f) continue;
            w[e]-=f; w[1^e]+=f;
            sum+=f; limit-=f;
            if (!limit) return sum;
          }
        }
        return sum;
      }
      int zkw() {
        int ret=0;
        while (spfa()) {
          memset(vis,0,sizeof(vis));
          memset(cur,0,sizeof(cur));
          ret+=dfs(S,INF)*dis[T];
        }
        return ret;
      }
    } G;
    
    bool cmp(int x,int y) {return a[x]<a[y];}
    
    void link(int l,int r) {
      if (l==r) return;
      for (ri i=l;i<=r;i++) id[i]=i;
      sort(id+l,id+r+1,cmp);
      for (ri i=l;i<=r;i++) t[i]=++cc;
      for (ri i=l;i<r;i++) {
        G.add_edge(t[i],t[i+1],INF,a[id[i+1]]-a[id[i]]);
        G.add_edge(t[i+1],t[i],INF,a[id[i+1]]-a[id[i]]);
      }
      int mid=(l+r)/2;
      for (ri i=l;i<=r;i++)
        if (id[i]<=mid) G.add_edge(id[i]+n,t[i],1,0); else G.add_edge(t[i],id[i],1,0);
      link(l,mid); link(mid+1,r);
    }
    
    int main(){
      scanf("%d %d",&n,&w);
      for (ri i=1;i<=n;i++) scanf("%d",&a[i]);
      for (ri i=1;i<=n;i++) G.add_edge(S,i,1,w);
      for (ri i=1;i<=n;i++) G.add_edge(i,T,1,0);
      for (ri i=1;i<=n;i++) G.add_edge(S,i+n,1,0);
      cc=T; link(1,n);
      cout<<G.zkw()<<endl;
    }
  • 相关阅读:
    【C/C++】qsort函数的使用方法和细节
    MOOC C++笔记(五):继承
    MOOC 数据库系统笔记(二):数据库系统的基本结构及其演变发展
    PTA A1015
    MOOC 数据库系统笔记(一):初步认识数据库系统
    PTA A1014
    MOOC C++笔记(四):运算符重载
    PTA A1013
    PTA A1011&A1012
    1.1.22 同样的文档,行数不一样
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11277867.html
Copyright © 2011-2022 走看看