zoukankan      html  css  js  c++  java
  • 清理雪道(bzoj 2502)

    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
    /*
        有源汇上下界最小流。
        设原来的源汇点为SS、TT,超级源汇点为S、T。 
        先按照可行流建立模型,然后由TT向SS连一条inf的边,跑可行流。
        那么现在可行流会聚积在TT到SS的边上,我们需要从TT往SS反流一遍最大流,使正的流量尽量小。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #define N 110
    #define M 21000
    #define inf 1000000000
    using namespace std;
    int head[N],dis[N],s[N],n,cnt=1,SS,TT,S,T;
    struct node{int v,f,pre;}e[M];
    queue<int> q;
    void add(int u,int v,int f){
        e[++cnt].v=v;e[cnt].f=f;e[cnt].pre=head[u];head[u]=cnt;
        e[++cnt].v=u;e[cnt].f=0;e[cnt].pre=head[v];head[v]=cnt;
    }
    bool bfs(){
        memset(dis,-1,sizeof(dis));
        q.push(S);dis[S]=0;
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].pre)
                if(e[i].f&&dis[e[i].v]==-1){
                    dis[e[i].v]=dis[u]+1;
                    q.push(e[i].v);
                }
        }
        return dis[T]!=-1;
    }
    int dinic(int x,int f){
        int rest=f;
        if(x==T) return f;
        for(int i=head[x];i;i=e[i].pre){
            if(!e[i].f||dis[e[i].v]!=dis[x]+1) continue;
            int t=dinic(e[i].v,min(rest,e[i].f));
            e[i].f-=t;e[i^1].f+=t;rest-=t;
        }
        if(rest==f) dis[x]=-1;
        return f-rest;
    }
    int main(){
        scanf("%d",&n);SS=0;TT=n+1;S=n+2,T=n+3;
        for(int i=1;i<=n;i++){
            int m,x;scanf("%d",&m);
            for(int j=1;j<=m;j++){
                scanf("%d",&x);
                s[i]++;s[x]--;add(i,x,inf);
            }
        }
        for(int i=1;i<=n;i++){
            if(s[i]>0) add(i,T,s[i]);
            if(s[i]<0) add(S,i,-s[i]);
            add(SS,i,inf);
            add(i,TT,inf);
        }
        add(TT,SS,inf);
        while(bfs()) dinic(S,inf);
        head[SS]=e[head[SS]].pre;
        head[TT]=e[head[TT]].pre;
        for(int i=head[S];i;i=e[i].pre)
            e[i].f=e[i^1].f=0;
        for(int i=head[T];i;i=e[i].pre)
            e[i].f=e[i^1].f=0;
        int sum=e[cnt].f;
        add(S,TT,inf);add(SS,T,inf);
        while(bfs()) sum-=dinic(S,inf);
        printf("%d",sum);
        return 0;
    }
  • 相关阅读:
    JavaScript 中的undefined and null 学习
    html5 file upload and form data by ajax
    openresty + lua-resty-weedfs + weedfs + graphicsmagick动态生成缩略图(类似淘宝方案)
    ubuntu10.04 安装oracle server 版 笔记
    windows xp + mysql5.5 + phpmyadmin insert 中文繁體
    (原创)ubuntu 10.04+ruby1.9.2+rails3 安装记录
    ruby簡單的代碼行統計工具
    Ruby中如何复制对象 (deep clone)(转载)
    vi 常用命令使用說明
    一个小公司老板的日常管理日记,希望能让创业的朋友学到东西(转载)
  • 原文地址:https://www.cnblogs.com/harden/p/6629147.html
Copyright © 2011-2022 走看看