zoukankan      html  css  js  c++  java
  • P2754 星际转移问题

    题解:利用分层图思想加入时间概念,第0天地球编号设为0,月球编号设为n+1,空间站编号在1到n之间。对于每一天都新建n+2个点表示不同天不同地方的情况,这样加入了时间概念。源点与第0天的地球建立一条容量k的边表示初始所有人在地球上,不同点与上一天相同点建立一条容量正无穷的边表示任意地方可以容纳无限多的人,每一天的月球与汇点建立一条正无穷的点,因为本题只加边所以可在上一天的残余网络上增广,直到汇点的容量大于等于k位置。判断无法到达用并查集判断即可。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=760,M=(2*N+1e3)*2,inf=1e9;
      4 int h[N],e[M],ne[M],f[M],idx;
      5 int d[N],cur[N],p[30];
      6 int n,m,k,S,T;
      7 struct node
      8 {
      9     int sum,r,id[30];
     10 }ship[30];
     11 int find(int x)
     12 {
     13     if(p[x]!=x)p[x]=find(p[x]);
     14     return p[x];
     15 }
     16 int get(int day,int u)
     17 {
     18     return day*(n+2)+u;
     19 }
     20 void add(int a,int b,int c)
     21 {
     22     ne[idx]=h[a],e[idx]=b,f[idx]=c,h[a]=idx++;
     23     ne[idx]=h[b],e[idx]=a,f[idx]=0,h[b]=idx++;
     24 }
     25 bool bfs()
     26 {
     27     memset(d,-1,sizeof d);
     28     queue<int>q;
     29     q.push(S);
     30     cur[S]=h[S];
     31     d[S]=0;
     32     while(q.size())
     33     {
     34         int t=q.front();
     35         q.pop();
     36         for(int i=h[t];i!=-1;i=ne[i])
     37         {
     38             int j=e[i];
     39             if(d[j]==-1&&f[i])
     40             {
     41                 d[j]=d[t]+1;
     42                 cur[j]=h[j];
     43                 if(j==T)return true;
     44                 q.push(j);
     45             }
     46         }
     47     }
     48     return false;
     49 }
     50 int find(int u,int limit)
     51 {
     52     if(u==T)return limit;
     53     int flow=0;
     54     for(int i=cur[u];i!=-1&&flow<limit;i=ne[i])
     55     {
     56         int j=e[i];
     57         cur[u]=i;
     58         if(d[j]==d[u]+1&&f[i])
     59         {
     60             int t=find(j,min(f[i],limit-flow));
     61             if(!t)d[j]=-1;
     62             f[i]-=t,f[i^1]+=t,flow+=t;
     63         }
     64     }
     65     return flow;
     66 }
     67 int dinic()
     68 {
     69     int r=0,flow;
     70     while(bfs())while(flow=find(S,inf))r+=flow;
     71     return r;
     72 }
     73 int main()
     74 {
     75     memset(h,-1,sizeof h);
     76     cin>>n>>m>>k;
     77     S=N-1,T=N-2;
     78     for(int i=0;i<=n+1;i++)p[i]=i;
     79     for(int i=0;i<m;i++)
     80     {
     81         int x,y;
     82         scanf("%d%d",&x,&y);
     83         ship[i].sum=x;
     84         ship[i].r=y;
     85         for(int j=0;j<y;j++)
     86         {
     87             int id;
     88             scanf("%d",&id);
     89             if(id==-1)id=n+1;
     90             ship[i].id[j]=id;
     91             if(j)
     92             {
     93                 int de=ship[i].id[j-1];
     94                 p[find(de)]=find(id);
     95             }
     96         }
     97     }
     98     if(find(0)!=find(n+1))puts("0");
     99     else
    100     {
    101         add(S,get(0,0),k);
    102         add(get(0,n+1),T,inf);
    103         int res=0,day=1;
    104         while(1)
    105         {
    106             for(int i=0;i<=n+1;i++)
    107             add(get(day-1,i),get(day,i),inf);
    108             add(get(day,n+1),T,inf);
    109             for(int i=0;i<m;i++)
    110             {
    111                 int r=ship[i].r;
    112                 int x=get(day-1,ship[i].id[(day-1)%r]);
    113                 int y=get(day,ship[i].id[day%r]);
    114                 add(x,y,ship[i].sum);
    115             }
    116             res+=dinic();
    117             if(res>=k)break;
    118             day++;
    119         }
    120         printf("%d
    ",day);
    121     }
    122 }
  • 相关阅读:
    MFC学习篇(二):error LNK2005 及其解决方法
    MFC学习篇(一):用OpenCV显示视频
    记一次mysql安装!
    常用数据对应关系及简单介绍
    docker
    月份及星期 缩写
    java 面对对象笔记
    linux小案例 定时备份数据库
    rpm_yum_开发工具的安装
    shell入门
  • 原文地址:https://www.cnblogs.com/flyljz/p/13673249.html
Copyright © 2011-2022 走看看