zoukankan      html  css  js  c++  java
  • 【LOJ6225&网络流24题】火星探险问题(费用流)

    题意:

     思路:

    【问题分析】

    最大费用最大流问题。

    【建模方法】

    把网格中每个位置拆分成网络中两个节点<i.a>,<i.b>,建立附加源S汇T。

    1、对于每个顶点i,j为i东边或南边相邻的一个节点,连接节点<i.b>与节点<j.a>一条容量为无穷大,费用为0的有向边。

    2、从每个石块顶点<i.a>到<i.b>连接一条容量为1,费用为1的有向边。

    3、从每个非障碍顶点<i.a>到<i.b>连接一条容量为无穷大,费用为0的有向边。

    4、从S到登陆舱位置<(1,1),a>连接一条容量为探测车数,费用为0的有向边。

    5、从传送器位置<(P,Q),a>到T连接一条容量为探测车数,费用为0的有向边。

    求最大费用最大流,最大费用流值就是最多的岩石标本的数量。所有满流边构成多条满流路径,每条从S到T的路径就是一个探测车的路径。

    【建模分析】

    这个问题可以看做是出发点和目的地唯一的网络运输问题。每个石块点的价值只能计算一次,所以容量限制要设为1,“多个探测车可以在同一时间占据同一位置”,非障碍点内部要有一条容量为无穷大的

    边。直接求费用流即可。

    输出方案不能直接记增广路上的点,要重新dfs一遍

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef long double ld;
      7 typedef pair<int,int> PII;
      8 typedef pair<ll,ll> Pll;
      9 typedef vector<int> VI;
     10 typedef vector<PII> VII;
     11 typedef pair<ll,ll>P;
     12 #define N  500000
     13 #define M  1000000
     14 #define INF 1e9
     15 #define fi first
     16 #define se second
     17 #define MP make_pair
     18 #define pb push_back
     19 #define pi acos(-1)
     20 #define mem(a,b) memset(a,b,sizeof(a))
     21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     23 #define lowbit(x) x&(-x)
     24 #define Rand (rand()*(1<<16)+rand())
     25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     26 #define ls p<<1
     27 #define rs p<<1|1
     28 
     29 const ll MOD=1e9+7,inv2=(MOD+1)/2;
     30       double eps=1e-6;
     31       int dx[4]={-1,1,0,0};
     32       int dy[4]={0,0,-1,1};
     33 
     34 struct node
     35 {
     36     int x,y;
     37 }p[N];
     38 
     39 VI c;
     40 
     41 int head[N],vet[N],nxt[N],len1[N],len2[N],dis[N],inq[N],q[N],pre[N][2],num[50][50][2],a[50][50],f[N],
     42     s,S,T,tot,ans1,ans2,n,m;
     43 
     44 int read()
     45 {
     46    int v=0,f=1;
     47    char c=getchar();
     48    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     49    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     50    return v*f;
     51 }
     52 
     53 void add(int a,int b,int c,int d)
     54 {
     55     nxt[++tot]=head[a];
     56     vet[tot]=b;
     57     len1[tot]=c;
     58     len2[tot]=d;
     59     head[a]=tot;
     60 
     61     nxt[++tot]=head[b];
     62     vet[tot]=a;
     63     len1[tot]=0;
     64     len2[tot]=-d;
     65     head[b]=tot;
     66 }
     67 
     68 int spfa()
     69 {
     70     rep(i,1,s)
     71     {
     72         dis[i]=-INF;
     73         inq[i]=0;
     74     }
     75     int t=0,w=1;
     76     q[1]=S; dis[S]=0; inq[S]=1;
     77     while(t<w)
     78     {
     79         t++; int u=q[t%(s+5)]; inq[u]=0;
     80         int e=head[u];
     81         while(e)
     82         {
     83             int v=vet[e];
     84             if(len1[e]&&dis[u]+len2[e]>dis[v])
     85             {
     86                 dis[v]=dis[u]+len2[e];
     87                 pre[v][0]=u;
     88                 pre[v][1]=e;
     89                 if(!inq[v])
     90                 {
     91                     w++; q[w%(s+5)]=v; inq[v]=1;
     92                 }
     93             }
     94             e=nxt[e];
     95         }
     96     }
     97     if(dis[T]==-INF) return 0;
     98     return 1;
     99 }
    100 
    101 void dfs(int x,int y)
    102 {
    103     int u=num[x][y][1];
    104     int e=head[u];
    105     while(e)
    106     {
    107         if(f[e]>=len1[e^1])
    108         {
    109             e=nxt[e];
    110             continue;
    111         }
    112 
    113         int v=vet[e];
    114         if(v==num[x+1][y][0])
    115         {
    116             f[e]++; c.pb(0);
    117             dfs(x+1,y);
    118             return;
    119         }
    120          else if(v==num[x][y+1][0])
    121          {
    122              f[e]++; c.pb(1);
    123              dfs(x,y+1);
    124              return;
    125          }
    126         e=nxt[e];
    127     }
    128 }
    129 
    130 void mcf()
    131 {
    132     int k=T,t=INF;
    133     while(k!=S)
    134     {
    135         int e=pre[k][1];
    136         t=min(t,len1[e]);
    137         k=pre[k][0];
    138     }
    139     ans1+=t;
    140     k=T;
    141     while(k!=S)
    142     {
    143         int e=pre[k][1];
    144         len1[e]-=t;
    145         len1[e^1]+=t;
    146         ans2+=t*len2[e];
    147         k=pre[k][0];
    148     }
    149 }
    150 
    151 int main()
    152 {
    153     //freopen("1.in","r",stdin);
    154     //freopen("1.out","w",stdout);
    155     int car=read();
    156     n=read(),m=read();
    157     swap(n,m);
    158     rep(i,1,n)
    159      rep(j,1,m) a[i][j]=read();
    160     s=0;
    161     rep(i,1,n)
    162      rep(j,1,m)
    163       rep(k,0,1)
    164       {
    165           num[i][j][k]=++s;
    166           p[s].x=i; p[s].y=j;
    167       }
    168 
    169     S=++s,T=++s;
    170     p[S].x=p[S].y=1;
    171     p[T].x=n; p[T].y=m;
    172     rep(i,1,s) head[i]=0;
    173     tot=1;
    174     rep(i,1,n)
    175      rep(j,1,m)
    176      {
    177          if(a[i][j]==1) continue;
    178          add(num[i][j][0],num[i][j][1],INF,0);
    179          if(a[i][j]==2) add(num[i][j][0],num[i][j][1],1,1);
    180      }
    181     rep(i,1,n)
    182      rep(j,1,m)
    183      {
    184          if(a[i][j]==1) continue;
    185          if(i+1<=n&&a[i+1][j]!=1) add(num[i][j][1],num[i+1][j][0],INF,0);
    186          if(j+1<=m&&a[i][j+1]!=1) add(num[i][j][1],num[i][j+1][0],INF,0);
    187      }
    188     add(S,num[1][1][0],car,0);
    189     add(num[n][m][1],T,car,0);
    190     ans1=ans2=0;
    191     while(spfa()) mcf();
    192     rep(i,1,ans1)
    193     {
    194         c.clear();
    195         dfs(1,1);
    196         for(int j=0;j<c.size();j++) printf("%d %d
    ",i,c[j]);
    197     }
    198     return 0;
    199 
    200 }
  • 相关阅读:
    【LeetCode】1404. 将二进制表示减到 1 的步骤数
    【剑指Offer】面试题12. 矩阵中的路径(DFS)
    【LeetCode】994. 腐烂的橘子(BFS)
    【LeetCode】365. 水壶问题(BFS/裴蜀定理)
    【LeetCode】169. 多数元素(摩尔投票法)
    ASP.NET页面间传值
    SQL——基础概念
    SQL——登陆触发器实现限制IP
    SQL Server之null
    SQL Server服务器连接配置
  • 原文地址:https://www.cnblogs.com/myx12345/p/11768189.html
Copyright © 2011-2022 走看看