• CF-546E. Soldier and Traveling(网络最大流)


    CF传送门

    洛谷传送门


    解题思路

    把城市拆成两个点——入点(1~n)和出点(n+1~2n),然后以下情况连边:

    • 读入的边(入连向出),边的流量为max
    • 超级源点向所有城市入点连边,流量为a[i]
    • 所有城市入点向出点连边,流量为max
    • 所有城市出点向汇点连边,流量为b[i]

    跑一边最大流,若最大流结果等于b[i]的和,则可以达到目标,然后扫一遍图,输出方案。

    坑点比较多:

    1. 各种数组开两倍空间
    2. edge结构体开10倍空间
    3. 建图一定要建反边
    4. cnt初始化为-1或1
    5. 判断a[i]的和与b[i]的和是否相等
    6. 最后跑图统计答案时要求e[i].v必须在n+1~2n之间才是答案

    AC代码

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<queue>
      8 #include<set>
      9 #include<map>
     10 #include<vector>
     11 #include<iomanip>
     12 #include<ctime>
     13 #include<stack>
     14 using namespace std;
     15 const int maxn=205;
     16 const int maxx=0x3f3f3f3f;
     17 int n,m,s,t,a[maxn],b[maxn],p[201],cnt=-1,dis[205],vis[205],cur[205],ans,mp[maxn][maxn],anss;
     18 struct node{
     19     int v,cap,flow,next;
     20 }e[2005];
     21 void insert(int u,int v,int cap,int flow){
     22     cnt++;
     23     e[cnt].v=v;
     24     e[cnt].cap=cap;
     25     e[cnt].flow=flow;
     26     e[cnt].next=p[u];
     27     p[u]=cnt;
     28 }
     29 bool bfs(){
     30     queue<int> q;
     31     memset(dis,-1,sizeof(dis));
     32     q.push(s);
     33     dis[s]=0;
     34     while(!q.empty()){
     35         int u=q.front();
     36         q.pop();
     37         for(int i=p[u];i!=-1;i=e[i].next){
     38             int v=e[i].v;
     39             if(dis[v]==-1&&e[i].cap>e[i].flow){
     40                 dis[v]=dis[u]+1;
     41                 q.push(v);
     42             }
     43         } 
     44     }
     45     if(dis[t]==-1) return false;
     46     else return true;
     47 }
     48 long long dfs(int u,int maxflow){
     49     if(u==t||maxflow==0) return maxflow;
     50     long long flow=0;
     51     for(int &i=cur[u];i!=-1;i=e[i].next){
     52         int v=e[i].v;
     53         if(dis[v]==dis[u]+1){
     54             long long f=dfs(v,min(maxflow,e[i].cap-e[i].flow));
     55             e[i].flow+=f;
     56             e[i^1].flow-=f;
     57             flow+=f;
     58             maxflow-=f;
     59             if(maxflow==0) break; 
     60         }
     61     }
     62     return flow;
     63 }
     64 long long dinic(){
     65     long long fl=0; 
     66     while(bfs()){
     67         for(int i=0;i<=2*n+1;i++) cur[i]=p[i];
     68         fl+=dfs(s,maxx);
     69     }
     70     return fl;
     71 }
     72 int main()
     73 {
     74     memset(p,-1,sizeof(p));
     75     cin>>n>>m;
     76     s=0;
     77     t=2*n+1;
     78     for(int i=1;i<=n;i++){
     79         cin>>a[i];
     80         anss+=a[i];
     81         insert(s,i,a[i],0);
     82         insert(i,s,0,0);
     83         insert(i,i+n,maxx,0);
     84         insert(i+n,i,0,0);
     85     }
     86     for(int i=1;i<=n;i++){
     87         cin>>b[i];
     88         ans+=b[i];
     89         insert(n+i,t,b[i],0);
     90         insert(t,n+i,0,0);
     91     }
     92     if(ans!=anss){
     93         cout<<"NO";
     94         return 0;
     95     }
     96     for(int i=1;i<=m;i++){
     97         int u,v;
     98         cin>>u>>v;
     99         insert(u,v+n,maxx,0);
    100         insert(v+n,u,0,0);
    101         insert(v,u+n,maxx,0);
    102         insert(u+n,v,0,0);
    103     }
    104     if(dinic()!=ans) cout<<"NO";
    105     else{
    106         cout<<"YES
    ";
    107         for(int u=1;u<=n;u++){
    108             for(int i=p[u];i!=-1;i=e[i].next){
    109                 if((e[i].v>n&&e[i].v<=n+n)&&e[i].flow) mp[u][e[i].v-n]=e[i].flow;
    110             }
    111         }
    112         for(int i=1;i<=n;i++){
    113             for(int j=1;j<=n;j++){
    114                 cout<<mp[i][j]<<" ";
    115             }
    116             cout<<endl;
    117         }
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    CSUFT 1002 Robot Navigation
    CSUFT 1003 All Your Base
    Uva 1599 最佳路径
    Uva 10129 单词
    欧拉回路
    Uva 10305 给任务排序
    uva 816 Abbott的复仇
    Uva 1103 古代象形文字
    Uva 10118 免费糖果
    Uva 725 除法
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14493212.html
Copyright © 2020-2023  润新知