题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2324

题意:n+1个城市(0到n)。初始时K个 人都在0城市。城市之间有距离。要求(1)遍历完n个城市(有一个人遍历了某个城市就算这个城市被遍历了);(2)遍历i城市前必须遍历完前i-1个城 市,并且在遍历前i-1个城市时不能经过大于等于i的城市。在满足(1)(2)的前提下使得K个人走的总距离最小。

思路:我们先看在实际情况下可以怎么走。

(1)某个人遍历完某个城市后停在那里,以后不再遍历其他城市;

(2)某个人在遍历完一个城市后再接着遍历其他城市。

首先利用flody计算出d数组,d[i][j][k]表示只使用前i个城市从j到达k的最短路。每个点拆成两个点i,i+n+1,增加原点S和汇点T:

(1)(S,0,K,0),表示从0最多出去K个人;

(2)(i,i+n+1,INF,0),表示从一个城市中经过的人数无限制;

(3)(i,t,1,0),遍历i城市,作为i城市的流(因为最大流是n+1,所以每个点都有一个流向t的流量为1的流)

(4)(S,1+n+i,1,0), (i+n+1,j,INF,d[j][i][j]),一个人在遍历完i城市后继续遍历j城市。这里这个人为啥要从S运送到i+n+1呢?因为从0出去的最 多K个人,若城市大于K个,则必有一些人要遍历多于1个城市,也就是说,若城市小于K则这个流是没用的。那么到达i的人不是可以继续到达i+n+1进而继 续遍历其他的呢?因为最后的最大流是n+1,到达i的那个人去汇点了,作为i的流。从实际意义出发,若这个流最后使用了,就好比是在遍历完i后遍历j。若 这个流最后没有使用,就好比在遍历完i之后那个人就停在i了。

struct node
{
    int u,v,flow,cost,next;
};

node edges[N*100];
int head[N],e;

void add(int u,int v,int flow,int cost)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].cost=cost;
    edges[e].flow=flow;
    edges[e].next=head[u];
    head[u]=e++;
}

void Add(int u,int v,int flow,int cost)
{
    add(u,v,flow,cost);
    add(v,u,0,-cost);
}

int C[N],F[N],pre[N],s,t;
int visit[N];

int SPFA(int s,int t)
{
    clr(pre,-1);
    queue<int> Q;
    Q.push(s);
    int i;
    FOR0(i,t+1) C[i]=INF,F[i]=0,visit[i]=0;
    int u,v,c,f;
    C[s]=0; F[s]=INF;
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();

        visit[u]=0;
        for(i=head[u];i!=-1;i=edges[i].next)
        {
            v=edges[i].v;
            c=edges[i].cost;
            f=edges[i].flow;
            if(f>0&&C[v]>C[u]+c)
            {
                C[v]=C[u]+c;
                F[v]=min(F[u],f);
                pre[v]=i;
                if(!visit[v])
                {
                    Q.push(v);
                    visit[v]=1;
                }
            }
        }
    }
    return F[t];
}

int MCMF(int s,int t)
{
    int ans=0,i,temp,x;
    while(temp=SPFA(s,t))
    {
        for(i=t;i!=s;i=edges[pre[i]].u)
        {
            x=pre[i];
            ans+=temp*edges[x].cost;
            edges[x].flow-=temp;
            edges[x^1].flow+=temp;
        }
    }
    return ans;
}

int n,m,K,d[155][155][155],g[155][155];

int main()
{
    RD(n,m,K);
    int i,j,k;
    FOR0(i,n+1) FOR0(j,n+1)
    {
        if(i==j) g[i][j]=0;
        else g[i][j]=INF;
    }
    int x,y,z;
    while(m--)
    {
        RD(x,y,z);
        if(z<g[x][y]) g[x][y]=g[y][x]=z;
    }
    FOR0(k,n+1)
    {
        FOR0(i,n+1) FOR0(j,n+1)
        {
            g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
        }
        FOR0(i,n+1) FOR0(j,n+1) d[k][i][j]=g[i][j];
    }
    clr(head,-1); e=0;
    s=2*n+2; t=2*n+3;
    Add(s,0,K,0);
    for(i=0;i<=n;i++)
    {
        Add(i,1+n+i,INF,0);
        Add(s,1+n+i,1,0);
        Add(i,t,1,0);

        for(j=i+1;j<=n;j++) if(d[j][i][j]<INF)
        {
            Add(1+n+i,j,INF,d[j][i][j]);
        }
    }
    PR(MCMF(s,t));
}

BZOJ 2324 营救皮卡丘(最小费用最大流)的更多相关文章

  1. BZOJ-2324 营救皮卡丘 最小费用可行流+拆下界+Floyd预处理

    准备一周多的期末,各种爆炸,回来后状态下滑巨快...调了一晚上+80%下午 2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MB ...

  2. BZOJ 2324 营救皮卡丘

    http://www.lydsy.com/JudgeOnline/problem.php?id=2324 思路:最小费用最大流 考虑设数组d[k][i][j],代表只用前k个城市,i到j的最短路 然后 ...

  3. BZOJ 2324: [ZJOI2011]营救皮卡丘( floyd + 费用流 )

    昨晚写的题...补发一下题解... 把1~N每个点拆成xi, yi 2个. 预处理i->j经过编号不超过max(i,j)的最短路(floyd) S->0(K, 0), S->xi(1 ...

  4. BZOJ2324 [ZJOI2011]营救皮卡丘 【费用流】

    题目 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道 ...

  5. BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流

    传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...

  6. BZOJ 1061 志愿者招募(最小费用最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...

  7. bzoj 1070 [SCOI2007]修车(最小费用最大流)

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3515  Solved: 1411[Submit][Status] ...

  8. BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)

    不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...

  9. bzoj 3171: [Tjoi2013]循环格 最小费用最大流

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...

随机推荐

  1. struts2中的addActionError 、addFieldError、addActionMessage的方法

    一 addActionError ①概念addActionError是Action级别的错误消息 ②添加this.addActionError("错误信息"); ③显示<s: ...

  2. Concurrent Assertion

    Concurrent assertion中要求必须有clock,从而保证在每个clock edge都进行触发判断. assertion与design进行同步执行,concurrent assert只能 ...

  3. 为什么DIY报价----走出软件作坊:三五个人十来条枪 如何成为开发正规军(十二)[转]

    前段时间,写了一个开发.实施.服务费用计算三部曲. 水清则无鱼--走出软件作坊:三五个人十来条枪 如何成为开发正规军(八) 实施费用也能DIY--走出软件作坊:三五个人十来条枪 如何成为开发正规军(九 ...

  4. 【海岛帝国系列赛】No.3 海岛帝国:运输资源

    海岛帝国:运输资源 [试题描述] YSF考虑到“药师傅”帝国现在资源极度不平均,于是,商讨启用南水北调工程.YZM为首席工程师.现在,YSF由于工作紧张,准备军用物资和民用物资.但他要时时关注运输工程 ...

  5. 关于ScrollView中嵌套listview焦点滑动问题 解决

    (第三种,第四种简单推荐使用) 在这里我要提出的是,listview能滚动的前提是:当listview本身的高度小于listview里的子view. 第一种方法 只需在MainActivity中 找到 ...

  6. git-gui

    使用Git.Git GUI和TortoiseGit http://zengrong.net/post/1722.htm 但云桌面不能安装,则TortoiseGit不能使用! 只能想到用totalcmd ...

  7. React笔记_(1)_react概述

    React概述   React是一种很好的前端技术. 它将应用打散成独立的小模块,然后进行组装,完成开发. react远比angularjs难学的多. react依赖的如webpack等各种工具得先学 ...

  8. 学习Perl6: slice fastq file

    需求: 只获取 ath 物种的 hairpin 序列 文件格式如下所示,以>打头的为 header,紧跟的为序列[AUCG]+ (Perl5 regexp 格式) #!/usr/bin/env ...

  9. discuz阅读权限的设置作用

    为什么要有阅读权限?偶想很多新手有这个疑问吧,所以特开此帖说明下. 阅读权限的设置是帖子作者为了部分限制帖子的读者群.虽然网上发帖重在分享,但帖子(尤其精华帖子)是作者花时间和经历而写成的,不加阅读权 ...

  10. [Ogre][地形]OgreTerrain分析以及使用

    Ogre 1.7.2中的地形教程 ○读者可以对照着Ogre1.7.2中的terrain.h源码进行阅读加深理解,蓝色部分均为源码 ○去除了一些具体场景比如添加mesh,设置setAmbientLigh ...