zoukankan      html  css  js  c++  java
  • [CTSC1999][网络流24题]家园

    题目:洛谷P2754。

    题目大意:
    有$n$个空间站,$m$个飞船,每个飞船有各自的停靠站点,并且从第一个停靠站点开始,不断循环。每个飞船有不同的容量(-1为月球,0为地球)。每个飞船初始停在第一个停靠站上,每过1s就会到下一个停靠站。
    在空间站上的人可以选择上飞船,也可以选择不上飞船。
    现在有$k$个人要从地球到月球去,问至少要过多少秒(无解输出$0$)。
    解题思路:
    由于每一时刻状态都是不同的,而数据规模比较小,可以考虑网络流建分层图。
    枚举答案,每次从源点向当前状态的地球连一条容量inf的边,从当前状态向下一状态连一条容量为inf的边(人可以站在空间站而不一定要上船)。
    再对每个飞船,从当前状态停靠站向下一状态的下一停靠站连一条容量为飞船容量的边。
    然后每次加完边,都在原来的残量网络上跑网络流,并累计流量。当某一次得到的流量大于等于$k$时,输出答案即可。
    无解的情况,只需要定一个答案上界(如1000),当超过上界时就判为无解,输出0即可。

    C++ Code:

    #include<bits/stdc++.h>
    #define moon 23333
    struct edge{
    	int to,nxt,cap;
    }e[5000000];
    inline int readint(){
    	int c=getchar(),d=0,b=0;
    	for(;!isdigit(c);c=getchar())b=c=='-';
    	for(;isdigit(c);c=getchar())
    	d=(d<<3)+(d<<1)+(c^'0');
    	return b?-d:d;
    }
    int n,m,k,head[100000],cnt=1,iter[100000],level[100000],flow=0;
    inline void addedge(int u,int v,int flow){
    	e[++cnt]=(edge){v,head[u],flow};
    	head[u]=cnt;
    	e[++cnt]=(edge){u,head[v],0};
    	head[v]=cnt;
    }
    struct boat{
    	int h,sz,a[1000],now;
    }p[100];
    std::queue<int>q;
    void bfs(){
    	q.push(0);
    	memset(level,-1,sizeof level);
    	level[0]=0;
    	while(!q.empty()){
    		int u=q.front();
    		q.pop();
    		for(int i=head[u];i!=-1;i=e[i].nxt)
    		if(level[e[i].to]==-1&&e[i].cap>0){
    			level[e[i].to]=level[u]+1;
    			q.push(e[i].to);
    		}
    	}
    }
    int dfs(int u,int t,int f){
    	if(u==t)return f;
    	for(int &i=iter[u];i!=-1;i=e[i].nxt){
    		if(e[i].cap>0&&level[e[i].to]>level[u]){
    			int d=dfs(e[i].to,t,std::min(f,e[i].cap));
    			if(d){
    				e[i].cap-=d;
    				e[i^1].cap+=d;
    				return d;
    			}
    		}
    	}
    	return 0;
    }
    void dinic(){
    	for(;;){
    		memcpy(iter,head,sizeof iter);
    		bfs();
    		if(level[moon]==-1)return;
    		int f;
    		while(f=dfs(0,moon,0x3f3f3f3f))flow+=f;
    	}
    }
    int main(){
    	std::ios::sync_with_stdio(0);
    	n=readint(),m=readint(),k=readint();
    	memset(head,-1,sizeof head);
    	for(int i=1;i<=m;++i){
    		p[i].h=readint(),p[i].sz=readint();
    		p[i].now=1;
    		for(int j=1;j<=p[i].sz;++j)p[i].a[j]=readint();
    	}
    	std::cout.tie(0);
    	for(int ans=1;ans<=1000;++ans){
    		addedge(0,(n+1)*(ans-1)+1,0x3f3f3f3f);
    		for(int i=1;i<=n+1;++i)addedge((n+1)*(ans-1)+i+1,(n+1)*ans+i+1,0x3f3f3f3f);
    		for(int i=1;i<=m;++i){
    			int nxt=p[i].now+1;
    			if(nxt>p[i].sz)nxt=1;
    			int x=(n+1)*(ans-1)+p[i].a[p[i].now]+1,
    			y=(n+1)*ans+p[i].a[nxt]+1;
    			if(p[i].a[p[i].now]==-1)x=moon;
    			if(p[i].a[nxt]==-1)y=moon;
    			addedge(x,y,p[i].h);
    			p[i].now=nxt;
    		}
    		dinic();
    		if(flow>=k){
    			std::cout<<ans;
    			return EXIT_SUCCESS;
    		}
    	}
    	std::cout<<0;
    	return 0;
    }
    
  • 相关阅读:
    Windows编程系列:Windows中的消息
    python 日志 logging模块
    wx-xcx
    大坑:perspectiveTransform
    在移动硬盘上装系统
    Django
    双边滤波(Bilateral filter)
    Mesh Deformation with Laplacian Coordinates
    C++五十一篇 -- VS2017开发人员新闻无法联网
    idea 修改Git密码和账号后,Git提交账号的没有改变
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9009098.html
Copyright © 2011-2022 走看看