链接:https://www.oj.swust.edu.cn/oj/problem/show/1748
分析:这题最难的地方在于飞船的周期性,不同时间图不一样。。。考虑枚举天数,记Xn,m为第n天的第m个点,从Xn,m向Xn+1,l连一条边,m,l之间这一天有飞船,容量为飞船容量,然后从Xn,m向Xn+1,m连一条容量为无穷大,求从地球到月亮的最大流,当最大流>=k停止。
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<queue> 5 #include<cstring> 6 using namespace std; 7 const int maxn=1e3+5,INF=1e9; 8 struct Edge{ 9 int from,to,cap,flow; 10 Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} 11 }; 12 struct ISAP{ 13 int n,s,t,flow; 14 vector<Edge> edges; 15 vector<int> G[maxn]; 16 bool vis[maxn]; 17 int d[maxn],cur[maxn],p[maxn],num[maxn]; 18 19 void init(int n){ 20 this->n=n; 21 flow=0; 22 edges.clear(); 23 for(int i=0;i<n;i++)G[i].clear(); 24 } 25 26 void AddEdge(int from,int to,int cap){ 27 edges.push_back(Edge(from,to,cap,0)); 28 edges.push_back(Edge(to,from,0,0)); 29 G[from].push_back(edges.size()-2); 30 G[to].push_back(edges.size()-1); 31 } 32 33 void BFS(){ 34 memset(vis,0,sizeof(vis)); 35 queue<int>Q; 36 Q.push(t); 37 d[t]=0;vis[t]=1; 38 while(!Q.empty()){ 39 int x=Q.front();Q.pop(); 40 for(int i=0;i<G[x].size();i++){ 41 Edge &e=edges[G[x][i]^1]; 42 if(e.flow==e.cap)continue; 43 if(!vis[e.from]){ 44 vis[e.from]=1; 45 d[e.from]=d[x]+1; 46 Q.push(e.from); 47 } 48 } 49 } 50 } 51 52 int Augmemt(){ 53 int x=t,a=INF; 54 while(x!=s){ 55 Edge &e=edges[p[x]]; 56 a=min(a,e.cap-e.flow); 57 x=edges[p[x]].from; 58 } 59 x=t; 60 while(x!=s){ 61 edges[p[x]].flow+=a; 62 edges[p[x]^1].flow-=a; 63 x=edges[p[x]].from; 64 } 65 return a; 66 } 67 68 int Maxflow(int s,int t){ 69 this->s=s;this->t=t; 70 BFS(); 71 memset(num,0,sizeof(num)); 72 for(int i=0;i<n;i++)num[d[i]]++; 73 int x=s; 74 memset(cur,0,sizeof(cur)); 75 while(d[s]<n){ 76 if(x==t){ 77 flow+=Augmemt(); 78 x=s; 79 } 80 int ok=0; 81 for(int i=cur[x];i<G[x].size();i++){ 82 Edge &e=edges[G[x][i]]; 83 if(e.cap>e.flow&&d[x]==d[e.to]+1){ 84 ok=1; 85 p[e.to]=G[x][i]; 86 cur[x]=i; 87 x=e.to; 88 break; 89 } 90 } 91 if(!ok){ 92 int m=n-1; 93 for(int i=0;i<G[x].size();i++){ 94 Edge &e=edges[G[x][i]]; 95 if(e.cap>e.flow)m=min(m,d[e.to]); 96 } 97 if(--num[d[x]]==0)break; 98 num[d[x]=m+1]++; 99 cur[x]=0; 100 if(x!=s)x=edges[p[x]].from; 101 } 102 } 103 return flow; 104 } 105 }isap; 106 int n,m,k,day=0,moon=1000; 107 int fa[1005]; 108 int Find(int x){return fa[x]==x?x:fa[x]=Find(fa[x]);} 109 struct SpaceShip{ 110 int h,c; 111 vector<int> stop; 112 }ss[25]; 113 inline int read(){ 114 int t; 115 scanf("%d",&t); 116 if(t==-1)return moon; 117 return t; 118 } 119 int main(){ 120 // freopen("e:\in.txt","r",stdin); 121 scanf("%d%d%d",&n,&m,&k); 122 isap.init(moon+1); 123 for(int i=0;i<=moon;i++)fa[i]=i; 124 for(int i=0;i<m;i++){ 125 int stop; 126 scanf("%d%d",&ss[i].h,&ss[i].c); 127 for(int j=0;j<ss[i].c;j++){ 128 stop=read(); 129 ss[i].stop.push_back(stop); 130 if(j){ 131 int x=Find(stop),y=Find(ss[i].stop[0]); 132 if(x!=y)fa[x]=y; 133 } 134 } 135 } 136 if(Find(0)!=Find(moon))cout<<0<<endl; 137 else{ 138 while(isap.flow<k){ 139 for(int i=1;i<=n;i++)isap.AddEdge(i+day*n,i+(day+1)*n,INF); 140 for(int i=0;i<m;i++){ 141 int u=ss[i].stop[day%ss[i].c]+day*n,v=ss[i].stop[(day+1)%ss[i].c]+(day+1)*n; 142 if(ss[i].stop[day%ss[i].c]==0)u=0; 143 if(ss[i].stop[(day+1)%ss[i].c]==moon)v=moon; 144 if(ss[i].stop[(day+1)%ss[i].c]==0||ss[i].stop[day%ss[i].c]==moon)continue; 145 isap.AddEdge(u,v,ss[i].h); 146 } 147 isap.Maxflow(0,moon); 148 day++; 149 } 150 cout<<day<<endl; 151 } 152 return 0; 153 }