• BZOJ 2502: 清理雪道


    BZOJ 2502: 清理雪道

    标签(空格分隔): OI-BZOJ OI-最小流 OI-上下界网络流


    Time Limit: 10 Sec
    Memory Limit: 128 MB


    Description
    滑雪场坐落在FJ省西北部的若干座山上。
    从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向。
    你的团队负责每周定时清理雪道。你们拥有一架直升飞机,每次飞行可以从总部带一个人降落到滑雪场的某个地点,然后再飞回总部。从降落的地点出发,这个人可以顺着斜坡向下滑行,并清理他所经过的雪道。
    由于每次飞行的耗费是固定的,为了最小化耗费,你想知道如何用最少的飞行次数才能完成清理雪道的任务。
    Input

    输入文件的第一行包含一个整数n (2 <= n <= 100) – 代表滑雪场的地点的数量。接下来的n行,描述1~n号地点出发的斜坡,第i行的第一个数为mi (0 <= mi < n) ,后面共有mi个整数,由空格隔开,每个整数aij互不相同,代表从地点i下降到地点aij的斜坡。每个地点至少有一个斜坡与之相连。
    Output

       输出文件的第一行是一个整数k – 直升飞机的最少飞行次数。
    

    Sample Input

    8

    1 3

    1 7

    2 4 5

    1 8

    1 8

    0

    2 6 5

    0

    Sample Output

    4
    HINT

    Source

    2011福建集训


    Solution####

    有上下界网络流,弧的下界为1,求最小流


    Code####

    
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<stdlib.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int read()
    {
    	int s=0,f=1;char ch=getchar();
    	while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}
    	while('0'<=ch&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    	return s*f;
    }
    int S,T,SS,TT,n,m,np;
    int A[105],B[105],jr[10005],jc[10005];
    int be[100005],bn[200005],bv[200005],bl[200005],bw=1;
    void put(int u,int v,int l)
    {bw++;bn[bw]=be[u];be[u]=bw;bv[bw]=v;bl[bw]=l;}
    int d[100005];
    bool spfa(int S,int T)
    {
    	for(int i=1;i<=np;i++)
    	   d[i]=10000000;
    	d[S]=1;
    	queue<int>q;
    	for(q.push(S);!q.empty();)
    	   {int u=q.front();q.pop();
    	    for(int i=be[u],v;i;i=bn[i])
    	       if(d[v=bv[i]]>d[u]+1&&bl[i])
    	         {d[v]=d[u]+1;
    	          q.push(v);
    			 }
    	   }
    	return d[T]!=10000000;
    }
    int ans;
    int dinic(int u,int mf,int T)
    {
    	if(mf==0)return 0;
    	if(u==T)return mf;
    	int sum=0;
    	for(int i=be[u],v;i;i=bn[i])
    	   if(d[v=bv[i]]==d[u]+1)
    	     {int f=dinic(v,min(mf-sum,bl[i]),T);
    	      bl[i]-=f;
    	      bl[i^1]+=f;
    	      sum+=f;
    	     }
    	return sum;
    }
    bool p[101][101];
    int main()
    {
    	n=read();
    	S=++np,T=++np;
    	for(int i=1;i<=n;i++)
    	    A[i]=++np,
    	    put(S,A[i],1000000),
    	    put(A[i],S,0),
    	    put(A[i],T,1000000),
    	    put(T,A[i],0);
    	for(int i=1;i<=n;i++)
    	   {int m=read();
    	    for(int j=1,v;j<=m;j++)
    		    v=read(),
    			put(A[i],A[v],1e9),
    			put(A[v],A[i],0),
    			jc[A[i]]++,jr[A[v]]++;
    	   }
    	SS=++np,TT=++np;
    	int sumr=0;
    	for(int i=1;i<=np;i++)
    	   {if(jr[i]-jc[i]>0)put(SS,i,jr[i]-jc[i]),put(i,SS,0),sumr+=jr[i]-jc[i];
    	    else put(i,TT,jc[i]-jr[i]),put(TT,i,0);
    	   }
    	put(T,S,1e9);
    	put(S,T,0);
    	while(spfa(SS,TT))ans+=dinic(SS,1e9,TT);
    	if(ans<sumr)
    	  {printf("-1
    ");return 0;}
    	ans=bl[bw];
    	bl[bw]=bl[bw-1]=0;
    	while(spfa(T,S))ans-=dinic(T,1e9,S);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    为什么今日头条是技术牛人收割机(FW)
    独家|浅谈用户行为数据的价值挖掘(PPT)(FW)
    深度学习笔记
    "堕落"的头条,还是"不堪"的民众?
    理解传统企业的问题与困惑
    人工智能在医疗领域究竟要怎么玩?(FW)
    佟崴嵬
    youtube true view的逻辑
    AI第一性原理
    域对象的属性和请求的转发重定向
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5242256.html
Copyright © 2020-2023  润新知