zoukankan      html  css  js  c++  java
  • BZOJ 2502: 清理雪道

    题目大意:
    求最少的链能覆盖一个DAG,可以重复。

    题解:

    比较显然的上下界最小流,其实没有上界。

    代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int cnt,n,S,T,SS,TT,d[1000005],q[1000005],cur[1000005],last[1000005],h[1000005];
    struct node{
    	int to,next,cap;
    }e[1000005];
    void add(int a,int b,int c){
    	e[++cnt].to=b;
    	e[cnt].cap=c;
    	e[cnt].next=last[a];
    	last[a]=cnt;
    }
    void ADD(int a,int b,int c){
    	add(a,b,c);
    	add(b,a,0);
    }
    void build(int a,int b,int minn,int maxx){
    	ADD(a,b,maxx-minn);
    	d[a]-=minn;
    	d[b]+=minn;
    }
    int bfs(int S,int T){
    	for (int i=1; i<=n+4; i++) h[i]=-1;
    	h[S]=0;
    	int head=0,tail=1;
    	q[tail]=S;
    	while (head<tail){
    		int x=q[++head];
    		for (int i=last[x]; i; i=e[i].next){
    			int V=e[i].to;
    			if (e[i].cap && h[V]==-1){
    				h[V]=h[x]+1;
    				q[++tail]=V;
    			}
    		}
    	}
    	return h[T]!=-1;
    }
    int dfs(int x,int T,int low){
    	if (x==T) return low;
    	int used=0;
    	for (int i=cur[x]; i; i=e[i].next){
    		int V=e[i].to;
    		if (e[i].cap && h[V]==h[x]+1){
    			int w=dfs(V,T,min(e[i].cap,low-used));
    			e[i].cap-=w;
    			e[i^1].cap+=w;
    			cur[x]=i;
    			used+=w;
    			if (used==low) return low;
    		}
    	}
    	if (!used) h[x]=-1;
    	return used;
    }
    int dinic(int S,int T){
    	int ans=0;
    	while (bfs(S,T)){
    		for (int i=1; i<=n+4; i++) cur[i]=last[i];
    		ans+=dfs(S,T,1e9);
    	}
    	return ans;
    }
    int main(){
    	cnt=1;
    	scanf("%d",&n);
    	int S=n+1,T=n+2,SS=n+3,TT=n+4;
    	for (int x=1; x<=n; x++){
    		int len;
    		scanf("%d",&len);
    		for (int i=1; i<=len; i++){
    			int y;
    			scanf("%d",&y);
    			build(x,y,1,1e6);
    		}
    	}
    	for (int i=1; i<=n; i++){
    		build(S,i,0,1e6);
    		build(i,T,0,1e6);
    	}
    	for (int i=1; i<=T; i++){
    		if (d[i]>0) ADD(SS,i,d[i]);
    		else ADD(i,TT,-d[i]);
    	}
    	ADD(T,S,1e6);
    	dinic(SS,TT);
    	int ans=e[cnt].cap;
    	e[cnt].cap=e[cnt-1].cap=0;
    	printf("%d
    ",ans-dinic(T,S));
    	return 0;
    }
    

      

  • 相关阅读:
    设计模式总结
    设计模式之工厂
    C#
    UML画图总结
    UML视频总结
    类图
    读取文件信息
    HMAC算法加密
    SHA_1计算消息摘要
    获取指定长度的随机字符串
  • 原文地址:https://www.cnblogs.com/silenty/p/8808315.html
Copyright © 2011-2022 走看看