zoukankan      html  css  js  c++  java
  • POJ 3614 Sunscreen

    网络流,Dinic G++ 964ms水过,SAP 620ms AC

    源点到每一个防晒霜建边,容量为cover[i];

    每一个防晒霜与它能保护的奶牛之间连一条边,容量为1;

    每一个奶牛连到汇点一条边,容量为1。

    最大流就是答案。

    Dinic模板:

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 6000 + 10;
    const int INF = 0x7FFFFFFF;
    struct Edge
    {
        int from, to, cap, flow;
        Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f) {}
    };
    vector<Edge>edges;
    vector<int>G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    int n, m, s, t;
    
    void init()
    {
        for (int i = 0; i < maxn; i++)
            G[i].clear();
        edges.clear();
    }
    void AddEdge(int from, int to, int cap)
    {
        edges.push_back(Edge(from, to, cap, 0));
        edges.push_back(Edge(to, from, 0, 0));
        int w = edges.size();
        G[from].push_back(w - 2);
        G[to].push_back(w - 1);
    }
    bool BFS()
    {
        memset(vis, 0, sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!Q.empty())
        {
            int x = Q.front();
            Q.pop();
            for (int i = 0; i<G[x].size(); i++)
            {
                Edge e = edges[G[x][i]];
                if (!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }
    int DFS(int x, int a)
    {
        if (x == t || a == 0)
            return a;
        int flow = 0, f;
        for (int &i = cur[x]; i<G[x].size(); i++)
        {
            Edge e = edges[G[x][i]];
            if (d[x]+1 == d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                edges[G[x][i]].flow+=f;
                edges[G[x][i] ^ 1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0) break;
            }
        }
        if(!flow) d[x] = -1;
        return flow;
    }
    int dinic(int s, int t)
    {
        int flow = 0;
        while (BFS())
        {
            memset(cur, 0, sizeof(cur));
            flow += DFS(s, INF);
        }
        return flow;
    }
    
    int C,L;
    int minSPF[maxn],maxSPF[maxn];
    int SPF[maxn];
    
    bool judge(int a,int b)
    {
        if(SPF[a]>=minSPF[b]&&SPF[a]<=maxSPF[b])
            return 1;
        return 0;
    }
    
    int main()
    {
        //0 源点 C+L+1汇点 1--L 防晒霜,L+1--L+C奶牛
        scanf("%d%d",&C,&L);
        init();
        s=0;t=C+L+1;
    
        for(int i=1;i<=C;i++)
            scanf("%d%d",&minSPF[i],&maxSPF[i]);
    
        for(int i=1;i<=L;i++)
        {
            int x;
            scanf("%d%d",&SPF[i],&x);
            AddEdge(0,i,x);
        }
    
        for(int i=1;i<=L;i++)
            for(int j=1;j<=C;j++)
                if(judge(i,j))
                    AddEdge(i,j+L,1);
    
        for(int i=L+1;i<=C+L;i++) AddEdge(i,t,1);
    
        printf("%d
    ",dinic(s,t));
        return 0;
    }

    SAP模板:

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=500000,maxm=3000000,INF=1<<30;
    int tot=0,S,T,n,m,cur[maxn],lay[maxn],gap[maxn],pre[maxn],V[maxm],Q[maxn],G[maxm],N[maxm],B[maxm],F[maxn];
    bool dw(int &x,int y)
    {
         if (y< x)
         {
           x=y;
           return 1;
          }
          return 0;
    }
    void add(int a,int b,int c)
    {
         ++tot;V[tot]=b;G[tot]=c;N[tot]=F[a];F[a]=tot;
         ++tot;V[tot]=a;G[tot]=0;N[tot]=F[b];F[b]=tot;
         B[tot]=tot-1;B[tot-1]=tot;
    }
    void bfs(int n)
    {
         int u,hd=0,tl=1,p;
         memset(lay,127,sizeof(lay));
         memset(gap,0,sizeof(gap));
         Q[1]=T;lay[T]=0;gap[0]=1;
         while (hd!=tl)
         {
           u=Q[++hd];
           for (p=F[u];p;p=N[p])
             if (G[B[p]]>0&&lay[V[p]]>=n)
             {
                 lay[V[p]]=lay[u]+1;
                 gap[lay[V[p]]]++;
                 Q[++tl]=V[p];
                 cur[V[p]]=B[p];
             }
         }
    }
    inline int sap(int n)
    {
        int u=S,v,flow,ret=0,mL,cnt=0,x,y;
        memset(pre,0,sizeof(pre));bfs(n);
        u=S;
        while (lay[S]< n)
        {
            cnt++;
            for (int &p=cur[u];p;p=N[p])
              if (G[p]>0&&lay[u]==lay[V[p]]+1) break;
            if (cur[u])
            {
                v=V[cur[u]];
                pre[v]=u;
                u=v;
                if (v==T)
                {
                    flow=INF;
                    x=T;
                    while (x!=S)
                    {
                        x=pre[x];
                        dw(flow,G[cur[x]]);
                    }
                    ret+=flow;
                    if (ret>=INF) return ret;
                    x=T;
                    while (x!=S)
                    {
                        x=pre[x];
                        G[cur[x]]-=flow;
                        G[B[cur[x]]]+=flow;
                    }
                    u=S;
                }
            }else {
                      mL=n;
                      for (int p=F[u];p;p=N[p])
                        if (G[p]>0&&dw(mL,lay[V[p]]+1)) cur[u]=p;
                      gap[lay[u]]--;
                      if (gap[lay[u]]==0) return ret;
                      gap[mL]++;lay[u]=mL;
                      if (u!=S) u=pre[u];
                  }
    
        }
        return ret;
    }
    
    
    int C,L;
    int minSPF[maxn],maxSPF[maxn];
    int SPF[maxn];
    
    bool judge(int a,int b)
    {
        if(SPF[a]>=minSPF[b]&&SPF[a]<=maxSPF[b])
            return 1;
        return 0;
    }
    
    int main()
    {
        //0 源点 C+L+1汇点 1--L 防晒霜,L+1--L+C奶牛
        scanf("%d%d",&C,&L);
        S=0;T=C+L+1;
    
        for(int i=1;i<=C;i++)
            scanf("%d%d",&minSPF[i],&maxSPF[i]);
    
        for(int i=1;i<=L;i++)
        {
            int x;
            scanf("%d%d",&SPF[i],&x);
            add(0,i,x);
        }
    
        for(int i=1;i<=L;i++)
            for(int j=1;j<=C;j++)
                if(judge(i,j))
                    add(i,j+L,1);
    
        for(int i=L+1;i<=C+L;i++) add(i,T,1);
    
        printf("%d
    ",sap(C+L+1));
        return 0;
    }
  • 相关阅读:
    CPU深度学习模型推理性能抖动问题
    深度学习推理性能优化
    Winograd Convolution 推导
    Res-Family: From ResNet to SE-ResNeXt
    CPU二则
    CPU TFLOPS 计算
    深度学习专题
    计算系统中互联设备Survey
    深度学习框架演进史
    天池医疗AI大赛支持有感
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5169151.html
Copyright © 2011-2022 走看看