您的位置:首页 > 理论基础 > 计算机网络

省选专练「网络流 24 题」星际转移

2018-03-19 19:05 405 查看
分层图上网络流。
以时间为键值开点。
对于每一个仓库,(i,time-1)->(i,time)(INF)表示可以放永远。
对于动态的飞船(a[i][time-1],time-1)->(a[i][time],time)(w[i])表示这一天可以搬这么多
那么,枚举时间,在参量网络上继续跑最大流,直到跑满就完了。#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#define C c
using namespace std;
const int N=20000;
const int INF=1e9+7;
struct Front_star{
int u,v,w,nxt;
}e[N*4];
int cnt=1;
int first
={0};
void addedge(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].w=w;
e[cnt].v=v;
e[cnt].nxt=first[u];
first[u]=cnt;
}
void add(int u,int v,int w){
addedge(u,v,w);
addedge(v,u,0);
}
int n,m,k;
int S=9201;
int T=1;
int w
={0};
int a[101][101]={0};
int fa[101]={0};
int C[101]={0};//record a new start
int getfa(int x){
if(x==fa[x]){
return x;
}
else{
return fa[x]=getfa(fa[x]);
}
}
void uni(int x,int y){
int dx=getfa(x);
int dy=getfa(y);
fa[dx]=dy;
}
int d[50001]={0};
int bfs(){
memset(d,-1,sizeof(d));
queue<int> q;
q.push(S);
d[S]=1;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w>0&&d[v]==-1){
d[v]=d[x]+1;
q.push(v);
}
}
}
return d[T]!=-1;
}
int dfs(int st,int ed,int nowdat){
int dat=0;
if(st==ed)
return nowdat;
for(int i=first[st];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w>0&&d[v]==d[st]+1){
int now=min(nowdat-dat,e[i].w);
now=dfs(v,ed,now);
dat+=now;
e[i].w-=now;
e[i^1].w+=now;
}
}
if(!dat){
d[st]=-2;
}
return dat;
}
int Dinic(){
int ans=0;
while(bfs()){
// cout<<"#$@#"<<endl;
ans+=dfs(S,T,0x3f3f3f3f);
}
return ans;
}
int main(){
scanf("%d%d%d",&n,&m,&k);n+=2;
for(int i=1;i<=n;i++){
fa[i]=i;
}
for(int i=1;i<=m;i++){
scanf("%d",&w[i]);
scanf("%d",&a[i][0]);
for(int j=1;j<=a[i][0];j++){
scanf("%d",&a[i][j]);
a[i][j]+=2;
if(j!=1){
uni(a[i][j],a[i][j-1]);
}
}
}
if(getfa(1)!=getfa(2)){
cout<<0<<endl;
return 0;
}
add(S,2,k);
for(int i=1;i<=m;i++){
C[i]=1;
}
int nowdat=0;
int stream=0;
int ans=0;
while(nowdat<k){
// cout<<ans<<" "<<nowdat<<endl;
ans++;
for(int i=1;i<=n;i++){
add(i+(ans-1)*n,i+ans*n,INF);
}
for(int i=1;i<=m;i++){
int p=C[i]+1;
if(p>a[i][0]){
p=1;
}
add(a[i][C[i]]+n*(ans-1),a[i][p]+n*ans,w[i]);
C[i]=p;
}
T=ans*n+1;
nowdat+=Dinic();
// cout<<ans<<" "<<nowdat<<endl;
}
cout<<ans<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: