• 网络流24题之星际转移问题


    一开始以为跑费用流,后来看了题解才知道可以按天建图。

    1.从源点向每一天的地球链接一条INF

    2.从每一天的月亮向汇点链接一条INF

    3.从上一天的每一个节点向当天的对应节点链接一条INF(因为人们可以留在中转站等一等嘛)

    4.针对每一艘飞船,获取其上一天的位置,再获取这一天的位置,在这两个点之间连一条容量为飞船满载人数的流

    每次新加一天然后跑到最大流超过k即可

    至于无解的情况只要当ans达到一个很大的值的时候跳出来即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1e5+10,inf=1e9;
     4 int head[N],cnt=-1,v[N],h[N],p[N],n,m,k,s,t,day[25][25];
     5 queue<int>q;
     6 struct node{
     7     int to,nex,w;
     8 }e[N<<1];
     9 void add(int x,int y,int w)
    10 {
    11     e[++cnt].to=y;e[cnt].w=w;e[cnt].nex=head[x];head[x]=cnt;
    12     e[++cnt].to=x;e[cnt].w=0;e[cnt].nex=head[y];head[y]=cnt;
    13 }
    14 bool bfs(int x,int y)
    15 {
    16     memset(v,-1,sizeof(v));
    17     v[x]=0;q.push(x);
    18     while(!q.empty())
    19     {
    20         int x=q.front();q.pop();
    21         for(int i=head[x];i!=-1;i=e[i].nex)
    22         {
    23             int y=e[i].to;
    24             if(v[y]!=-1||!e[i].w)continue;
    25             v[y]=v[x]+1;q.push(y);
    26         }
    27     }
    28     return v[y]!=-1;
    29 }
    30 int dfs(int x,int w,int yy)
    31 {
    32     if(!w||x==yy)return w;int s=0;
    33     for(int i=head[x];i!=-1;i=e[i].nex)
    34     {
    35         int y=e[i].to;
    36         if(v[y]!=v[x]+1||!e[i].w)continue;
    37         int flow=dfs(y,min(w-s,e[i].w),yy);
    38         if(!flow){v[y]=-1;continue;}
    39         s+=flow;e[i].w-=flow;e[i^1].w+=flow;
    40         if(s==w)return s;
    41     }
    42     return s;
    43 }
    44 int dinic(int x,int y)
    45 {
    46     int tmp=0;
    47     while(bfs(x,y))
    48     {
    49         tmp+=dfs(x,inf,y);
    50     }
    51     return tmp;
    52 }
    53 int main()
    54 {
    55     scanf("%d%d%d",&n,&m,&k);
    56     n+=2;memset(head,-1,sizeof(head));
    57     for(int i=1;i<=m;++i)
    58     {
    59         scanf("%d%d",&h[i],&p[i]);
    60         for(int j=0;j<p[i];++j)
    61         {
    62             scanf("%d",&day[i][j]);
    63             day[i][j]+=2;
    64         }
    65     }
    66     s=10001,t=10000;int ans=0;int sum=0;
    67     while(ans<=500)
    68     {
    69         add(s,ans*n+2,inf);
    70         add(ans*n+1,t,inf);
    71         if(ans)
    72         {
    73             for(int i=0;i<=n;++i)
    74             add((ans-1)*n+i,ans*n+i,inf);
    75             for(int i=1;i<=m;++i)
    76             {
    77                 add((ans-1)*n+day[i][(ans-1)%p[i]],ans*n+day[i][ans%p[i]],h[i]);
    78             }
    79         }
    80         sum+=dinic(s,t);
    81         if(sum>=k)
    82         {
    83             printf("%d
    ",ans);
    84             return 0;
    85         }
    86         ans++;
    87     }
    88     puts("0");
    89     return 0;
    90 }
  • 相关阅读:
    7.ps相关选项
    6.ps的大U和小u区别
    5.进程优先级
    4.状态间的六种转换情况
    3.进程的不同状态
    2.进程与程序的关系
    1.进程概念
    不换行
    for引用变量
    脚本进阶
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8358324.html
Copyright © 2020-2023  润新知