zoukankan      html  css  js  c++  java
  • 网络流板子/费用流板子 2018南京I题+2016青岛G题

    2018南京I题:

    dinic,链式前向星,数组队列,当前弧优化,不memset全部数组,抛弃满流点,bfs只找一条增广路,每次多路增广

    #include <bits/stdc++.h>
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    using namespace std;
    const int maxn=2e3+10,maxm=2e6+10;
    const int INF=0x3f3f3f3f;
    const int mod=1e9+7;
    const double PI=acos(-1.0);
    //head
    int casn,n,m,k;
    class mxf{public:
      struct node{int to,next;ll cap;}e[maxm<<1];
      int cur[maxn],head[maxn],que[maxn],dis[maxn],nume=1,s,t;
      inline void adde(int a,int b,ll c){e[++nume]={b,head[a],c};head[a]=nume;}
      inline void add(int a,int b,ll c){adde(a,b,c);adde(b,a,0);}
      void init(int n=maxn-1){memset(head,0,(n+1)<<2);nume=1;}
      bool bfs(){
        memset(dis,-1,(t+1)<<2);
        dis[t]=0,que[0]=t;
        int tp=0,ed=1;
        while(tp!=ed){
          int now=que[tp++];tp%=maxn;
          for(int i=head[now];i;i=e[i].next){
    				int to=e[i].to;
    				if(dis[to]==-1&&e[i^1].cap){
    					dis[to]=dis[now]+1;
    					if(to==s) return true;
    					que[ed++]=to;ed%=maxn;
    				}
          }
        }
        return false;
      }
      ll dfs(int now,ll flow=0x3f3f3f3f){
        if(now==t||flow==0) return flow;
        ll use=0;
        for(int &i=head[now];i&&use!=flow;i=e[i].next){
            int to=e[i].to;
            if(dis[to]+1!=dis[now])continue;
            ll tmp=dfs(to,min(e[i].cap,flow-use));
            e[i].cap-=tmp,e[i^1].cap+=tmp,use+=tmp;
        }
        if(!use) dis[now]=-1;
        return use;
      }
      ll getflow(int ss,int tt){
      	s=ss,t=tt;ll ans=0;
        memcpy(cur,head,(t+1)<<2);
        while(bfs()){
          ans+=dfs(s);
    			memcpy(head,cur,(t+1)<<2);
        }
        return ans;
      }
    }net;
    int main() {IO;
      cin>>n>>m>>k;
      int s=n+m+1,t=n+m+10,ss=n+m+2;
      net.init(t);net.add(s,ss,k);
      rep(i,1,n){
        net.add(s,i,1);net.add(ss,i,1);
        int x;cin>>x;
        while(x--){
    			int y;cin>>y;
    			net.add(i,n+y,1);
        }
      }
      while(m--) net.add(n+m+1,t,1);
      cout<<net.getflow(s,t);
    	return 0;
    }
    

     2016青岛G

    原始对偶算法+dijkstra正权化

    #include <bits/stdc++.h>
    #define endl '
    '
    #define ll long long
    #pragma GCC optimize("Ofast")
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    using namespace std;
    const int maxn=2e3+10,maxm=2e6+10;
    const double eps=1e-4;
    int casn,n,m,k;
    class mcf{public:
      #define tpp double
      struct node{int to;ll cap;tpp cost;int rev;};
      int prev[maxn],pree[maxn];
      tpp dis[maxn],cost,h[maxn];
      ll f;
      vector<node> g[maxn];
      void init(int n=maxn-2){rep(i,0,n+1) g[i].clear();}
      inline void add(int from,int to,ll cap,tpp cost){
        g[from].push_back({to,cap,cost,(int)g[to].size()});
        g[to].push_back({from,0,-cost,(int)g[from].size()});
      }
      tpp getcost(int s,int t){
        f=0,cost=0;
        fill(h,h+1+t,0);
        while(1){
            #define pdi pair<tpp,int>
            priority_queue<pdi,vector<pdi>,greater<pdi> >que;
            fill(dis,dis+t+1,1e10);
            dis[s]=0;que.push(make_pair(0,s));
            while(!que.empty()){
              auto now=que.top();que.pop();
              if(dis[now.second]<now.first)continue;
              int x=now.second;
              int cnt=0;
              for(auto &i:g[x])
                if(i.cap>0&&dis[i.to]>eps+dis[x]+h[x]-h[i.to]+i.cost){
                  dis[i.to]=dis[x]+i.cost+h[x]-h[i.to];
                  prev[i.to]=x;
                  pree[i.to]=cnt++;
                  que.push(make_pair(dis[i.to],i.to));
                }else cnt++;
            }
            if(dis[t]>=1e9)break;
            rep(i,0,t) h[i]+=dis[i];
            ll d=1e9;
            for(int now=t;now!=s;now=prev[now])
              d=min(d,g[prev[now]][pree[now]].cap);
            if(d==1e9)break;
            f+=d;cost+=d*h[t];
            for(int now=t;now!=s;now=prev[now]){
              node &e=g[prev[now]][pree[now]];
              e.cap-=d,g[now][e.rev].cap+=d;
            }
        }
        return cost;
      }
    }net;
    int a[maxn],b[maxn];
    int main() {IO;
      cout<<fixed<<setprecision(2);
      cin>>casn;
      while(casn--){
        cin>>n>>m;
        int s=n+1,t=n+2;
        net.init(t);
        rep(i,1,n){
          cin>>a[i]>>b[i];
          int k=min(a[i],b[i]);
          a[i]-=k,b[i]-=k;
          if(a[i])net.add(s,i,a[i],0);
          if(b[i])net.add(i,t,b[i],0);
        }
        while(m--){
          int x,y,z;double p;
          cin>>x>>y>>z>>p;
          p=-log(1-p);
          if(z>0) net.add(x,y,1,0);
          if(z>1) net.add(x,y,z-1,p);
        }
        double ans=1.0-exp(-net.getcost(s,t));
        cout<<ans<<endl;
      }
    	return 0;
    }
    

     EK+spfa

    #include <bits/stdc++.h>
    #define endl '
    '
    #define ll long long
    #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
    using namespace std;
    const int maxn=1e3+10,maxm=1e5+10;
    const double eps=1e-8;
    int casn,n,m,k;
    class mcf{public:
      #define tpp double
      int nume=1,s,t,mflow;
      int head[maxn],flow[maxn],pre[maxn];
      tpp dis[maxn],mcost;
      struct node{int to,next,cap;tpp cost;}e[maxm<<1];
      void init(int n=maxn-10){
        fill(head,head+n+2,0);
        nume=1,mflow=mcost=0;
      }
      inline void add(int from,int to,int cap,tpp cost){
          e[++nume]={to,head[from],cap,cost};head[from]=nume;
          e[++nume]={from,head[to],0,-cost};head[to]=nume;
      }
      bool vis[maxn];
      queue<int>q;
      bool spfa(){
          fill(dis,dis+2+t,1e9);
          fill(vis,vis+2+t,false);
          dis[s]=0;flow[s]=1e9;q.push(s);
          while (!q.empty()){
              int now=q.front();q.pop();
              vis[now]=false;
              for (int i=head[now];i;i=e[i].next){
                  int to=e[i].to;
                  tpp cost=e[i].cost;
                  if (e[i].cap&&dis[now]+cost+eps<dis[to]){
                      dis[to]=dis[now]+cost;
                      flow[to]=min(flow[now],e[i].cap);
                      pre[to]=i;
                      if (!vis[to]){
                          vis[to]=true;
                          q.push(to);
                      }
                  }
              }
          }
          return dis[t]<1e9;
      }
      void update(){
          int x=t;
          while (x!=s){
              int i=pre[x];
              e[i].cap-=flow[t];
              e[i^1].cap+=flow[t];
              x=e[i^1].to;
          }
          mflow+=flow[t];
          mcost+=(tpp)flow[t]*dis[t];
      }
      double getcost(int s,int t){
          this->s=s;this->t=t;
          while (spfa())update();
          return mcost;
      }
    }net;
    int a[maxn],b[maxn];
    int main() {IO;
      cout<<fixed<<setprecision(2);
      while(cin>>casn){
        while(casn--){
          cin>>n>>m;
          int s=n+1,t=n+2;
          net.init(t);
          rep(i,1,n){
            cin>>a[i]>>b[i];
            int k=min(a[i],b[i]);
            a[i]-=k,b[i]-=k;
            if(a[i])net.add(s,i,a[i],0);
            if(b[i])net.add(i,t,b[i],0);
          }
          while(m--){
            int x,y,z;double p;
            cin>>x>>y>>z>>p;
            p=-log(1-p);
            if(z>0) net.add(x,y,1,0);
            if(z>1) net.add(x,y,z-1,p);
          }
          double ans=net.getcost(s,t);
          ans=exp(-ans);
          ans=1.0-ans;
          cout<<ans<<endl;
        }
      }
    	return 0;
    }
    
  • 相关阅读:
    javaweb 安全传输签名机制
    GC详解及Minor GC和Full GC触发条件总结
    程序员的人性思考(上)
    LeetCode 845——数组中的最长山脉
    LeetCode 386——字典序的第 K 小数字
    LeetCode 386——字典序排数
    LeetCode 135——分发糖果
    Ubuntu 16.04 安装显卡驱动后循环登录和无法设置分辨率的一种解决方案
    在 Ubuntu 下安装 Deepin 的 QQ、微信、百度云和迅雷等软件
    腾讯 2019 春季暑期实习生提前批笔试——技术研究与数据分析
  • 原文地址:https://www.cnblogs.com/nervendnig/p/10777628.html
Copyright © 2011-2022 走看看