• [CTSC1999]家园(网络流)


    题目描述

    由于人类对自然资源的消耗,人们意识到大约在 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。

     

    输入输出样例

    输入样例#1: 复制
    2 2 1
    1 3 0 1 2
    1 3 1 2 -1
    
    输出样例#1: 复制
    5

    说明

    none!




    又发现了一道神题;

    网上说这题综合了信息学和物理上的狭义相对论

    不愧是ctsc的题啊

    本题的建模是真的难想啊

    由于数据范围较小,可以对每一天进行考虑。

    考虑每一天时,对每个太空站都建个新的点代表当前天的太空站,地球和月球也新建。

    从源点向地球连容量为inf的边,月球向汇点连容量为inf的边。

    然后每个太空站可以从上一天留下inf个人,所以从前一天连一条容量为inf的边。

    考虑每个太空船,可以从前一天所在的点转移hi个人过来,所以连一条容量为hi的边。

    然后跑最大流,最大流为当前天可送达的人数

    建完边直接从残量网络继续跑就行了

    无解可以用并查集判,也可以判如果天数大于500,即一个一个的送,经过所有点都送不完的话,就无解。




     1 #include<bits/stdc++.h>
     2 using namespace std;
     3  
     4 inline void read(int &x) {
     5     x=0;int f=1;char ch=getchar();
     6     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
     7     for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);x*=f;
     8 }
     9  
    10 inline void print(int x) {
    11     if(x<0) putchar('-'),x=-x;
    12     if(!x) return ;print(x/10),putchar((x%10)^48);
    13 }
    14 inline void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    15  
    16 #define maxn 1000050
    17 
    18 int n,m,s,t,max_flow,tot=1,k;
    19 int head[maxn],dis[maxn],vis[maxn],a[200][200],num[200],v[200];
    20 struct edge{int to,nxt,w;}e[maxn<<1];
    21 
    22 void add(int u,int v,int w) {e[++tot]=(edge){v,head[u],w},head[u]=tot;}
    23 void ins(int u,int v,int w) {add(u,v,w),add(v,u,0);}
    24 
    25 int bfs() {
    26     memset(vis,0,sizeof vis);
    27     memset(dis,63,sizeof dis);//write(dis[0]);
    28     queue<int > q;q.push(s);vis[s]=1;dis[s]=0;
    29     while(!q.empty()) {
    30         int now=q.front();q.pop();vis[now]=0;
    31         for(int i=head[now];i;i=e[i].nxt)
    32             if(e[i].w>0&&dis[e[i].to]>dis[now]+1) {
    33                 dis[e[i].to]=dis[now]+1;
    34                 if(!vis[e[i].to]) vis[e[i].to]=1,q.push(e[i].to);
    35             }
    36     }return dis[t]<1e9;
    37 }
    38 
    39 int dfs(int u,int flow) {
    40     if(u==t) return flow;
    41     for(int i=head[u];i;i=e[i].nxt)
    42         if(e[i].w>0&&dis[e[i].to]==dis[u]+1) {
    43             int f=dfs(e[i].to,min(flow,e[i].w));
    44             if(f>0) {e[i].w-=f,e[i^1].w+=f;return f;}
    45         }
    46     dis[u]=-1;return 0;
    47 }
    48 
    49 int dinic() {
    50     max_flow=0;
    51     while(bfs()) {
    52         int flow;
    53         while((flow=dfs(s,1e9))) max_flow+=flow;
    54     }return max_flow;
    55 }
    56 
    57 int main() {
    58     s=0,t=1e4;
    59     read(n),read(m),read(k);
    60     for(int i=1;i<=m;i++) {
    61         read(v[i]),read(num[i]);
    62         for(int j=0;j<num[i];j++) read(a[i][j]),a[i][j]+=2;
    63     }
    64     int ans=1,res=0;
    65      ins(s,0*(n+2)+2,1e9);
    66         ins(0*(n+2)+1,t,1e9);
    67     while(1) {
    68         
    69         ins(s,ans*(n+2)+2,1e9);
    70         ins(ans*(n+2)+1,t,1e9);
    71         if(ans) {
    72             for(int i=1;i<=n;i++) ins((ans-1)*(n+2)+i+2,ans*(n+2)+i+2,1e9);
    73             for(int i=1;i<=m;i++) ins((ans-1)*(n+2)+a[i][(ans-1)%num[i]],ans*(n+2)+a[i][ans%num[i]],v[i]);
    74         }
    75         
    76         res+=dinic();if(res>=k) return write(ans),0;
    77         ans++;if(ans==500) return puts("0"),0;
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    Chapter 8. 面向对象(类库、委托)
    Chapter 8. 面向对象(多态--接口)
    练习:C# -- 多态
    Chapter 8. 面向对象(多态--抽象类)
    Chapter 8. 面向对象(多态--虚方法)
    Chapter 8. 面向对象(继承)
    Chapter 8. 面向对象(封装)
    Chapter 8. 面向对象(类、对象、字段、方法、属性、构造函数)
    练习、C# 结构体、冒泡排序
    1月19日(HTML之旅) CSS样式表
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10587915.html
Copyright © 2020-2023  润新知