zoukankan      html  css  js  c++  java
  • 网络流24题总结和题解

    大体按照难度阵营

    t0 

    1.飞行员配对方案问题 

    这是个二分图匹配模板 但是这个输出方案套路还是要 掌握起来~

    大概是 我们跑网络流 一定能获得两个东西

    1.最大最小可行流数值和最大流数值

    2.一个可行的跑的方案 这个方案的特点是按照加边顺序进行增广 也就是说 加边满足字典序时 就可以按字典序跑了

    我们得到1 不停地增广 我们得到二 就是寻找跑满流量的正向边

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define maxn 10005
     5 #define inf 200000000
     6 int n,m,k=0,l,a,b,c,d[maxn],cur[maxn],visit[maxn],s=0,t;
     7 struct edge{int from,to,cap,flow;};vector<int>g[maxn];vector<edge>edges;
     8 void add_edge(int f,int t,int c){g[f].push_back(k);g[t].push_back(k+1);
     9     edges.push_back({f,t,c,0});edges.push_back({t,f,0,0});k+=2;
    10 }bool bfs(){queue<int>q;q.push(s);for(int i=1;i<=t;i++)d[i]=inf;d[s]=0;
    11     visit[s]=1,q.push(s);
    12     while(!q.empty()){int u=q.front();q.pop();visit[u]=0;
    13         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
    14             if(e.cap>e.flow&&d[e.to]>d[u]+1){d[e.to]=d[u]+1;if(!visit[e.to])q.push(e.to),visit[e.to]=1;
    15             }
    16         }
    17     }return d[t]!=inf;
    18 }ll dfs(int x,int a){if(x==t||a==0)return a;ll f=0,flow=0;
    19     for(int &i=cur[x];i<g[x].size();i++){edge &e=edges[g[x][i]];
    20         if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(e.cap-e.flow,a)))){
    21             e.flow+=f,edges[g[x][i]^1].flow-=f,flow+=f,a-=f;
    22         }
    23     }return flow;
    24 }ll mf(ll s,ll t){ll flow=0;
    25     while(bfs()){memset(cur,0,sizeof(cur));
    26         flow+=dfs(s,inf);
    27     }return flow;
    28 }int main(){cin>>m>>n;cin>>a>>b;t=n+1;
    29     for(int i=1;i<=m;i++)add_edge(s,i,1);for(int i=m+1;i<=n;i++)add_edge(i,t,1);
    30     while(a!=-1)add_edge(a,b,1),cin>>a>>b;
    31     cout<<mf(s,t)<<endl;
    32     for(int i=1;i<=m;i++)for(int j=0;j<g[i].size();j++){
    33             edge &e=edges[g[i][j]];if(e.flow==1)cout<<i<<" "<<e.to<<endl;
    34     }return 0;
    35 }
    View Code

    2.负载平衡问题

    这不知道跟网络流有个π关系

    啊 毫无关系 结论套一下就行 结论还是要掌握起来的

    代码吧

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int N=105;
     5 
     6 ll n,a[N],sum,s[N];
     7 
     8 int main()
     9 {
    10     cin>>n;
    11     for(int i=1;i<=n;i++)
    12     
    13     cin>>a[i],
    14     
    15     sum+=a[i];
    16     
    17     sum/=n;
    18     
    19     for(int i=1;i<=n;i++)
    20     
    21     a[i]-=sum,
    22     
    23     s[i]=s[i-1]+a[i];
    24     
    25     sort(s+1,s+n+1);
    26     
    27     sum=0;
    28     
    29     for(int i=1;i<=n;i++)
    30     
    31     sum+=abs(s[n/2+1]-s[i]);
    32     
    33     cout<<sum;
    34     return 0;
    35 }
    View Code

    t1

    1.餐巾计划问题

    首先费用流

    这个题也不知道是不是我搞错了 bzoj好像数据范围不大对 是不是有网络流以外的做法 我也不得而知

    这个题是个这样的模型:点代表天 每个天有s种决策 就拆为s个点 构造分层图 图与图之间链接操作边(边代表操作)

    简单来说叫做

    第一类:决策拆点

    难度评价 思维难度 2 代码难度 2 总体较为中档

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define maxn 4005
     4 #define ll long long
     5 #define inf 214700000
     6 struct edge{int from,to,cap,flow,cost;};
     7 int k=0;vector<edge>edges;vector<int>g[maxn];
     8 void add_edge(int f,int t,int v,int cost){g[f].push_back(k),g[t].push_back(k+1),k+=2,edges.push_back({f,t,v,0,cost}),edges.push_back({t,f,0,0,-cost});}
     9 int n,m,visit[maxn],d[maxn],a[maxn],p[maxn],aa,b,c,dd,s,t,m1,t1,m2,t2,x;
    10 ll sum=0,flow=0;
    11 bool spfa(){for(int i=1;i<maxn;i++)d[i]=inf;a[s]=inf;
    12     memset(visit,0,sizeof(visit));
    13     queue<int>q;q.push(s),d[s]=0;visit[s]=1;
    14     while(!q.empty()){int u=q.front();q.pop();visit[u]=0;
    15         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
    16             if(d[e.to]>d[u]+e.cost&&e.cap>e.flow){p[e.to]=g[u][i],a[e.to]=min(a[u],e.cap-e.flow),d[e.to]=d[u]+e.cost;
    17                 if(!visit[e.to])q.push(e.to),visit[e.to]=1;
    18             }
    19         }        
    20     }if(d[t]==inf)return 0;
    21     flow+=1ll*a[t];
    22     sum+=1ll*d[t]*a[t];int u=t;
    23     while(u!=s){edges[p[u]].flow+=a[t];edges[p[u]^1].flow-=a[t];
    24         u=edges[p[u]].from;
    25     }return true; 
    26 }
    27 int main(){cin>>n;s=0,t=2*n+1;
    28     for(int i=1;i<=n;i++){scanf("%d",&x);
    29         add_edge(s,i,x,0);add_edge(i+n,t,x,0);
    30     }scanf("%d%d%d%d%d",&m,&t1,&m1,&t2,&m2);
    31     for(int i=1;i<=n;i++){
    32         if(i+1<=n)add_edge(i,i+1,inf,0);if(i+t1<=n)add_edge(i,i+n+t1,inf,m1);
    33         if(i+t2<=n)add_edge(i,i+n+t2,inf,m2);add_edge(s,i+n,inf,m);
    34     }while(spfa());cout<<sum<<endl;
    35 }
    View Code

     

  • 相关阅读:
    chrome浏览器中安装以及使用Elasticsearch head 插件
    windows10 升级并安装配置 jmeter5.3
    linux下部署Elasticsearch6.8.1版本的集群
    【Rollo的Python之路】Python 爬虫系统学习 (八) logging模块的使用
    【Rollo的Python之路】Python 爬虫系统学习 (七) Scrapy初识
    【Rollo的Python之路】Python 爬虫系统学习 (六) Selenium 模拟登录
    【Rollo的Python之路】Python 爬虫系统学习 (五) Selenium
    【Rollo的Python之路】Python 爬虫系统学习 (四) XPath学习
    【Rollo的Python之路】Python 爬虫系统学习 (三)
    【Rollo的Python之路】Python sys argv[] 函数用法笔记
  • 原文地址:https://www.cnblogs.com/iboom/p/10045084.html
Copyright © 2011-2022 走看看