网络流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 }
原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8358324.html