网络流24题13
https://loj.ac/problem/6015
着重理解这题的建图是按照时间的分层图,对于时刻t的n个站点,他们的人员有2种来源 ,一是上一个时刻停留在该点的人员,另一种就是t-1通过飞船过来的人,对于每个新时刻维护好这几个边就行了
然后并查集判断有无解
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
const int maxn = 50;
const int inf = 0x3f3f3f3f;
int fa[maxn];
int cap[maxn];
int head[maxn*1000];
int all[maxn];
struct edge{
int v,nex,w;
}e[maxn*1000];
int tot = 0;
void addedge(int u,int v,int w){
e[tot] = (edge){v,head[u],w};
head[u] = tot++;
e[tot] = (edge){u,head[v],0};
head[v] = tot++;
}
vector<int> v[maxn];
int find(int now){
if(fa[now]== now) return now;
return find(fa[now]);
}
void un(int u,int v){
int fau = find(u);
int fav = find(v);
if(fau!=fav){
fa[fau] = fa[fav];
}
}
int deep[maxn*100];
bool bfs(int S,int T){
memset(deep, 0, sizeof(deep));
deep[S] = 1;
queue<int> q;
q.push(S);
while (!q.empty()) {
int now = q.front();
q.pop();
for(int i=head[now];i!=-1;i=e[i].nex){
int w = e[i].w;
int v = e[i].v;
if(deep[v]!=0 || w<=0) continue;
deep[v] = deep[now]+1;
q.push(v);
}
}
return deep[T];
}
int dfs(int now,int T,int maxflow){
if(now==T) return maxflow;
int all = 0;
for(int i=head[now];i!=-1 && all<maxflow;i=e[i].nex){
int v = e[i].v;
int w = e[i].w;
if(deep[v]!=deep[now]+1 || w<=0) continue;
int tt = dfs(v,T,min(maxflow-all,w));
e[i].w-=tt;
e[i^1].w+=tt;
all+=tt;
}
return all;
}
int main(int argc, const char * argv[]) {
memset(head, -1, sizeof(head));
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<=n+1;i++){
fa[i] = i;
}
int S = 0;
int T = 1;
for(int i=0;i<m;i++){
scanf("%d",&cap[i]);
scanf("%d",&all[i]);
for(int j=0;j<all[i];j++){
int tmp ;
scanf("%d",&tmp);
tmp++;
v[i].push_back(tmp);
if(j!=0){
un(v[i][0],tmp);
}
}
}
if(find(0)!=find(1)){
puts("0");
return 0;
}
int ans;
int maxflow = 0;
addedge(S, 1+1*(n+2), inf);
addedge(1*(n+2), T, inf);
for(int i=0;i<n+2;i++){
addedge(i+1*(n+2), i+(1+1)*(n+2), inf);
}
for(ans=2;;ans++){
addedge(S, 1+ans*(n+2), inf);
addedge(ans*(n+2), T, inf);
for(int i=0;i<m;i++){
int from = v[i][(ans-2+all[i])%all[i]];
int to = v[i][(ans-1+all[i])%all[i]];
addedge(from+(ans-1)*(n+2), to+ans*(n+2), cap[i]);
}
while (bfs(S,T)) {
maxflow+=dfs(S,T,inf);
}
if(maxflow>=k) break;
for(int i=0;i<n+2;i++){
addedge(i+ans*(n+2), i+(ans+1)*(n+2), inf);
}
}
printf("%d\n",ans-1);
return 0;
}

浙公网安备 33010602011771号