zoukankan      html  css  js  c++  java
  • LuoguP2754 [CTSC1999]家园(分层图,最大流)

    题目背景

    none!

    题目描述

    由于人类对自然资源的消耗,人们意识到大约在 2300 年之后,地球就不能再居住了。于是在月球上建立了新的绿地,以便在需要时移民。令人意想不到的是,2177 年冬由于未知的原因,地球环境发生了连锁崩溃,人类必须在最短的时间内迁往月球。

    现有 n 个太空站位于地球与月球之间,且有 m 艘公共交通太空船在其间来回穿梭。每个太空站可容纳无限多的人,而每艘太空船 i 只可容纳 H[i]个人。每艘太空船将周期性地停靠一系列的太空站,例如:(1,3,4)表示该太空船将周期性地停靠太空站 134134134…。每一艘太空船从一个太空站驶往任一太空站耗时均为 1。人们只能在太空船停靠太空站(或月球、地球)时上、下船。

    初始时所有人全在地球上,太空船全在初始站。试设计一个算法,找出让所有人尽快地全部转移到月球上的运输方案。

    对于给定的太空船的信息,找到让所有人尽快地全部转移到月球上的运输方案。

    输入输出格式

    输入格式:

    第 1 行有 3 个正整数 n(太空站个数),m(太空船个数)和 k(需要运送的地球上的人的个数)。其中 n<=13 m<=20, 1<=k<=50。

    接下来的 m 行给出太空船的信息。第 i+1 行说明太空船 pi。第 1 个数表示 pi 可容纳的人数 Hpi;第 2 个数表示 pi 一个周期停靠的太空站个数 r,1<=r<=n+2;随后 r 个数是停靠的太空站的编号(Si1,Si2,…,Sir),地球用 0 表示,月球用-1 表示。

    时刻 0 时,所有太空船都在初始站,然后开始运行。在时刻 1,2,3…等正点时刻各艘太空船停靠相应的太空站。人只有在 0,1,2…等正点时刻才能上下太空船。

    输出格式:

    程序运行结束时,将全部人员安全转移所需的时间输出。如果问题

    无解,则输出 0。

    解题思路:

    假如说告诉你多少天,问转移人口,那是不是会好一些,

    按时间分层,不同层相同点间按照时间方向建$inf$的边,

    跑一边最大流,源点是0时刻的地球,汇点是T时刻的月球。

    最大流就是人口。

    所以枚举判断好了。

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<vector>
      4 #include<cstring>
      5 #include<algorithm>
      6 const int oo=0x3f3f3f3f;
      7 struct pnt{
      8     int hd;
      9     int lyr;
     10     int now;
     11 }p[10000];
     12 struct ent{
     13     int twd;
     14     int lst;
     15     int vls;
     16 }e[1000000];
     17 int cnt;
     18 int n,m,k;
     19 int s,t;
     20 int size;
     21 int H[1000];
     22 int fa[1000];
     23 std::queue<int>Q;
     24 std::vector<int>st[1000];
     25 void ade(int f,int t,int v)
     26 {
     27     cnt++;
     28     e[cnt].twd=t;
     29     e[cnt].vls=v;
     30     e[cnt].lst=p[f].hd;
     31     p[f].hd=cnt;
     32     return ;
     33 }
     34 bool Bfs(void)
     35 {
     36     while(!Q.empty())
     37         Q.pop();
     38     for(int i=1;i<=size;i++)
     39         p[i].lyr=0;
     40     p[s].lyr=1;
     41     Q.push(s);
     42     while(!Q.empty())
     43     {
     44         int x=Q.front();
     45         Q.pop();
     46         for(int i=p[x].hd;i;i=e[i].lst)
     47         {
     48             int to=e[i].twd;
     49             if(p[to].lyr==0&&e[i].vls>0)
     50             {
     51                 p[to].lyr=p[x].lyr+1;
     52                 if(to==t)
     53                     return true;
     54                 Q.push(to);
     55             }
     56         }
     57     }
     58     return false;
     59 }
     60 int Dfs(int x,int fll)
     61 {
     62     if(x==t)
     63         return fll;
     64     for(int& i=p[x].now;i;i=e[i].lst)
     65     {
     66         int to=e[i].twd;
     67         if(p[to].lyr==p[x].lyr+1&&e[i].vls>0)
     68         {
     69             int ans=Dfs(to,std::min(fll,e[i].vls));
     70             if(ans>0)
     71             {
     72                 e[i].vls-=ans;
     73                 e[((i-1)^1)+1].vls+=ans;
     74                 return ans;
     75             }
     76         }
     77     }
     78     return 0;
     79 }
     80 int Dinic(void)
     81 {
     82     int ans=0;
     83     while(Bfs())
     84     {
     85         for(int i=1;i<=size;i++)
     86             p[i].now=p[i].hd;
     87         int dlt;
     88         while(dlt=Dfs(s,oo))
     89             ans+=dlt;
     90     }
     91     return ans;
     92 }
     93 int finf(int x)
     94 {
     95     return fa[x]==x?x:fa[x]=finf(fa[x]);
     96 }
     97 int main()
     98 {
     99 //    freopen("a.in","r",stdin);
    100     scanf("%d%d%d",&n,&m,&k);
    101     for(int i=1;i<=n+m+2;i++)fa[i]=i;
    102     for(int i=1;i<=m;i++)
    103     {
    104         scanf("%d",&H[i]);
    105         int tmp;
    106         scanf("%d",&tmp);
    107         for(int j=1;j<=tmp;j++)
    108         {
    109             int tl;
    110             scanf("%d",&tl);
    111             if(tl==0)tl=n+1;
    112             if(tl==-1)tl=n+2;
    113             st[i].push_back(tl);
    114             int f1=finf(tl);
    115             int f2=finf(n+2+i);
    116             if(f1!=f2)
    117                 fa[f1]=f2;
    118         }
    119     }
    120     if(finf(n+1)!=finf(n+2))
    121     {
    122         printf("%d
    ",0);
    123         return 0;
    124     }
    125     s=n+1;
    126     int N;
    127     int popu=0;
    128     for(N=0;;N++)
    129     {
    130         if(N)
    131         {
    132             for(int i=1;i<=n+m+2;i++)
    133             {
    134                 ade((N-1)*(n+m+2)+i,N*(n+m+2)+i,oo);
    135                 ade(N*(n+m+2)+i,(N-1)*(n+m+2)+i,0);
    136             }
    137         }
    138         size=(N+1)*(n+m+2);
    139         t=N*(n+m+2)+n+2;
    140         for(int i=1;i<=m;i++)
    141         {
    142             int tp=st[i][N%st[i].size()];
    143             if(tp!=n+1)
    144             {
    145                 ade(N*(n+m+2)+n+2+i,N*(n+m+2)+tp,H[i]);
    146                 ade(N*(n+m+2)+tp,N*(n+m+2)+n+2+i,0);
    147             }
    148             if(tp!=n+2)
    149             {
    150                 ade(N*(n+m+2)+tp,N*(n+m+2)+n+2+i,H[i]);
    151                 ade(N*(n+m+2)+n+2+i,N*(n+m+2)+tp,0);
    152             }
    153         }
    154         popu+=Dinic();
    155         if(popu<k);else break;
    156     }
    157     printf("%d
    ",N);
    158     return 0;
    159 }

     

  • 相关阅读:
    Beta阶段DAY1
    Beta阶段DAY2
    Beta阶段冲刺前准备
    Beta阶段Scrum 冲刺博客合集
    alpha阶段项目复审
    网络15软工个人作业5——软件工程总结
    软工网络15个人作业4——alpha阶段个人总结
    软件工程网络15个人作业3 (201521123051 谢庆圆)
    软件工程网络15专业结对编程
    软工网络15个人阅读作业2 (201521123051 谢庆圆)
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10205634.html
Copyright © 2011-2022 走看看