• cogs 736 星际转移 最大流


    cogs 736 星际转移
    题解:
    从小到大枚举答案days,然后网络流验证是否可以全部运走。假设当前验证的答案为days,那么我们就将太空船和太空站都拆成days+1个点,设编号分别为boat[i][1days+1],station[i][1days+1]。

    1. 如果说boat[i]在第j天在地球,那么此时boat[i][j]可以接受流量上限为H[i]的人上船,因此从S向boat[i][j]连边,容量H[i]。
    2. 如果boat[i]第j天在月球,此时boat[i][j]可以释放上限为H[i]的流量,因此boat[i][j]到T连边,容量H[i]。
    3. boat[i]第j天在太空站station[k],那么双方可以进行交换,boat[i][j]与station[k][j]互相连边,容量均为H[i]。
    4. 注意到boat[i]在第j天的流量是可以下传到第j+1天的,所以boat[i][j]向boat[i][j+1]连边容量为H[i]。
    5. 注意到太空站也是可以下传的,station[i][j]向station[i][j+1]连容量为INF的边。

    然后跑一下最大流,判断是否最大流小于人数,如果小于,则days再加一,在上一次的图上再加入一层点接着跑,否则结束输出days即可。

    至于判断无解,我是判断如果days=1000都没结束就输出无解。

    code

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define fcl fclose(stdin); fclose(stdout); return 0
    int n,m,K,days,S,T,res=0,cnt;
    int H[30],r[30],t[30][20];
    const int INF=0x7f7f7f7f;
    struct EDGE{
    	int to,next,flow;
    }edge[1000010];
    int head[100010],tot=1;
    inline void AddEdge(int a,int b,int c){
    	edge[++tot].to=b;
    	edge[tot].flow=c;
    	edge[tot].next=head[a];
    	head[a]=tot;
    }
    inline void Add(int a,int b,int c){
    	AddEdge(a,b,c); AddEdge(b,a,0);
    }
    int cur[100010],dis[100010],Q[100010];
    #define ty (edge[x].to)
    bool Bfs(){
    	memset(dis,0x7f,(cnt+1)<<2); dis[S]=0;
    	int s=1,t=1,u; Q[1]=S;
    	while(s<=t){
    		u=Q[s++];
    		for(int x=head[u];x;x=edge[x].next)
    			if(edge[x].flow&&dis[ty]==INF)
    				dis[ty]=dis[u]+1,Q[++t]=ty;
    	}
    	return dis[T]!=INF;
    }
    int Dfs(int u,int a){
    	if(u==T||a==0) return a;
    	int f2=0,f;
    	for(int& x=cur[u];x;x=edge[x].next){
    		if(edge[x].flow&&dis[ty]==dis[u]+1){
    			f=Dfs(ty,min(a,edge[x].flow));
    			edge[x].flow-=f; edge[x^1].flow+=f;
    			f2+=f; a-=f;
    			if(a==0) break;
    		}
    	}
    	return f2;
    }
    bool Judge(){
    	for(int i=1;i<=m;++i){
    		int x=days%r[i];
    		if(t[i][x]==0) Add(S,cnt+i,H[i]);
    		else if(t[i][x]==-1) Add(cnt+i,T,H[i]);
    		else AddEdge(cnt+i,cnt+m+t[i][x],INF),Add(cnt+m+t[i][x],cnt+i,INF);
    		Add(cnt+i,cnt+i+n+m,H[i]);
    	}
    	for(int i=1;i<=n;++i) Add(cnt+m+i,cnt+n+m+m+i,INF);
    	cnt+=(n+m);
    	while(Bfs()){
    		memcpy(cur,head,(cnt+1)<<2);
    		res+=Dfs(S,INF);
    	}
    	if(res<K) return true;
    	return false;
    }
    int main(){
    	freopen("home.in","r",stdin);
    	freopen("home.out","w",stdout);
    	
    	scanf("%d%d%d",&n,&m,&K);
    	S=1,T=2,cnt=2;
    	for(int i=1;i<=m;++i){
    		scanf("%d%d",&H[i],&r[i]);
    		for(int j=0;j<r[i];++j) scanf("%d",&t[i][j]);
    	}
    	if(K==0){puts("0");fcl;}
    	for(;days<1000&&Judge();++days);
    	if(days==1000) days=0;
    	printf("%d
    ",days);
    	fcl;
    }
    
  • 相关阅读:
    WebApp触屏版网站开发要点
    Web前端开发规范手册
    Web页面切图和CSS注意事项
    javascript中的一些基本方法收藏
    浅谈浏览器兼容性问题
    html 5 标签分类
    前端meta知多少
    浏览器内核信息整理
    Javascript中的undefined、null、""、0值和false的区别总结
    JQUERY中的AJAX应用
  • 原文地址:https://www.cnblogs.com/kito/p/7135631.html
Copyright © 2020-2023  润新知