zoukankan      html  css  js  c++  java
  • [有源汇最小流] Bzoj P2502 清理雪道

    Description

           滑雪场坐落在FJ省西北部的若干座山上。
    从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向。
    你的团队负责每周定时清理雪道。你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部。从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道。
    由于每次飞行的耗费是固定的,为了最小化耗费,你想知道如何用最少的飞行次数才能完成清理雪道的任务。
     

    Input

     
    输入文件的第一行包含一个整数n (2 <= n <= 100) – 代表滑雪场的地点的数量。接下来的n行,描述1~n号地点出发的斜坡,第i行的第一个数为mi (0 <= mi < n) ,后面共有mi个整数,由空格隔开,每个整数aij互不相同,代表从地点i下降到地点aij的斜坡。每个地点至少有一个斜坡与之相连。

    Output

     
           输出文件的第一行是一个整数k – 直升飞机的最少飞行次数。
     

    Sample Input

    8
    1 3
    1 7
    2 4 5
    1 8
    1 8
    0
    2 6 5
    0

    Sample Output

    4

    题解

    • s向每个点连[0,inf)的边,每个点向t连[0,inf)的边
    • 每条边的流量限制为[1,inf)
    • 对(s,t)跑最小流即可

    代码

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <queue>
     5 using namespace std;
     6 #define N 225
     7 #define inf 0x3f3f3f3f
     8 using namespace std;
     9 int n,cnt=1,s,t,ss,tt,ans,head[N],dis[N],d[N];
    10 struct edge{int to,c,from;}e[N*N*5];
    11 queue<int>Q;
    12 void insert(int x,int y,int z)
    13 {
    14     e[++cnt].to=y,e[cnt].c=z,e[cnt].from=head[x],head[x]=cnt;
    15     e[++cnt].to=x,e[cnt].c=0,e[cnt].from=head[y],head[y]=cnt;
    16 }
    17 bool bfs()
    18 {
    19     memset(dis,0,sizeof(dis)),dis[ss]=1;
    20     while (!Q.empty()) Q.pop();
    21     Q.push(ss);
    22     while (!Q.empty())
    23     {
    24         int u=Q.front(); Q.pop();
    25         for (int i=head[u];i;i=e[i].from)
    26             if (e[i].c&&!dis[e[i].to])
    27             {
    28                 dis[e[i].to]=dis[u]+1;
    29                 if (e[i].to==tt) return 1;
    30                 Q.push(e[i].to);
    31             }
    32     }
    33     return 0;
    34 }
    35 int dfs(int x,int maxf)
    36 {
    37     if (x==tt||!maxf) return maxf;
    38     int r=0;
    39     for (int i=head[x];i;i=e[i].from)
    40         if (e[i].c&&dis[e[i].to]==dis[x]+1)
    41         {
    42             int f=dfs(e[i].to,min(maxf-r,e[i].c));
    43             e[i].c-=f,e[i^1].c+=f,r+=f;
    44             if (r==maxf) break;
    45         }
    46     return r;
    47 }
    48 int main()
    49 {
    50     scanf("%d",&n);
    51     for (int i=1,x,y;i<=n;i++)
    52     {
    53         scanf("%d",&x);
    54         for (int j=1;j<=x;j++) scanf("%d",&y),d[i]--,d[y]++,insert(i,y,inf);
    55     }
    56     s=n+1,t=s+1,ss=t+1,tt=ss+1;
    57     for (int i=1;i<=n;i++)
    58     {
    59         insert(s,i,inf),insert(i,t,inf);
    60         if (d[i]>0) insert(ss,i,d[i]); else if (d[i]<0) insert(i,tt,-d[i]);
    61     }
    62     insert(t,s,inf);
    63     while (bfs()) dfs(ss,inf);
    64     ans=e[cnt].c,e[cnt].c=e[cnt^1].c=0;
    65     for (int i=head[ss];i;i=e[i].from) e[i].c=e[i^1].c=0;
    66     for (int i=head[tt];i;i=e[i].from) e[i].c=e[i^1].c=0;
    67     insert(ss,t,inf),insert(s,tt,inf);
    68     while (bfs()) ans-=dfs(ss,inf);
    69     printf("%d",ans);
    70 }
  • 相关阅读:
    OA常见问题和解决方案
    如何用Visio画venn(维恩)图
    小谈SQL表的连接
    记一次视图的应用
    常用sql语句备份
    EF中关系映射问题
    .net core 2.0的一次奇特经历
    .net core 下的Area注册
    win 10+ iis 10 部署.net core 1.1 web api
    AutoMapper差异内容备份
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11149592.html
Copyright © 2011-2022 走看看