zoukankan      html  css  js  c++  java
  • 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流

    1570: [JSOI2008]Blue Mary的旅行

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 388  Solved: 212
    [Submit][Status][Discuss]

    Description

    在一段时间之后,网络公司终于有了一定的知名度,也开始收到一些订单,其中最大的一宗来自B市。Blue Mary决定亲自去签下这份订单。为了节省旅行经费,他的某个金融顾问建议只购买U航空公司的机票。U航空公司的所有航班每天都只有一班,并且都是上午出发当天下午到达的,所以他们每人每天只能坐一班飞机。经过调查,他们得到了U航空公司经营的所有航班的详细信息,这包括每一航班的出发地,目的地以及最多能买到的某一天出发的票数。(注意: 对于一个确定的航班,无论是哪一天,他们最多能买到的那一天出发的票数都是相同的。) Blue Mary注意到他们一定可以只乘坐U航空公司的航班就从A市到达B市,但是,由于每一航班能买到的票的数量的限制,他们所有人可能不能在同一天到达B市。所以现在Blue Mary需要你的帮助,设计一个旅行方案使得最后到达B市的人的到达时间最早。

    Input

    第一行包含3个正整数N,M和T。题目中会出现的所有城市分别编号为1,2,…,N,其中城市A编号一定为1,城市B编号一定为N. U公司一共有M条(单向)航班。而连Blue Mary在内,公司一共有T个人要从A市前往B市。 以下M行,每行包含3个正整数X,Y,Z, 表示U公司的每一条航班的出发地,目的地以及Blue Mary最多能够买到的这一航班某一天出发的票数。(即:无论是哪一天,Blue Mary最多只能买到Z张U航空公司的从城市X出发到城市Y的机票。) 输入保证从一个城市到另一个城市的单向航班最多只有一个。

    Output

    仅有一行,包含一个正整数,表示最后到达B市的人的最早到达时间。假设他们第一次乘飞机的那一天是第一天。

    Sample Input

    3 3 5
    1 2 1
    2 3 5
    3 1 4

    Sample Output

    6

    HINT

    约定:
    2 <= N <= 50
    1 <= M <= 2450
    1 <= T <= 50
    1 <= X,Y <= N
    X != Y
    1 <= Z <= 50

    Source

    Solution

    一道比较有趣的建图。

    自己一开始想到了建图之后,用费用来搞天数,后来发现是不行的。

    正解是采用分层建图,枚举天,然后分层建图,即层与层之间相互连边,直到能跑出答案就退出。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define MAXN 100010
    #define MAXM 1000100 
    int N,M,t;
    struct EdgeNode{int next,to,cap,old;}edge[MAXM];
    int head[MAXN],cnt=1;
    inline void AddEdge(int u,int v,int w) {cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].cap=edge[cnt].old=w;}
    inline void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,0);}
    int h[MAXN],S,T,cur[MAXN];
    #define INF 0x7fffffff
    inline bool bfs()
    {
        queue<int>q;
        for (int i=S; i<=T; i++) h[i]=-1;
        h[S]=1; q.push(S);
        while (!q.empty())
            {
                int now=q.front(); q.pop();
                for (int i=head[now]; i; i=edge[i].next)
                    if (h[edge[i].to]==-1 && edge[i].cap)
                        h[edge[i].to]=h[now]+1,q.push(edge[i].to);
            }
        return h[T]!=-1;        
    }
    inline int dfs(int loc,int low)
    {
        if (loc==T) return low;
        int used=0,w;
        for (int i=cur[loc]; i; i=edge[i].next)
            if (edge[i].cap && h[edge[i].to]==h[loc]+1)
                {
                    w=dfs(edge[i].to,min(edge[i].cap,low-used));
                    edge[i].cap-=w; edge[i^1].cap+=w; used+=w;
                    if (used==low) return low;
                    if (edge[i].to) cur[loc]=i;
                }
        if (!used) h[loc]=-1;
        return used;
    }
    inline int Dinic()
    {
        int tmp=0;
        while (bfs())
            {
                for (int i=S; i<=T; i++) cur[i]=head[i];
                tmp+=dfs(S,INF);
            }
        return tmp;
    }
    struct eNode{int u,v,c;}e[MAXN];
    inline int id(int day,int id) {return day*N+id;}
    int main()
    {
        N=read(),M=read(),t=read();
        for (int i=1; i<=M; i++) e[i].u=read(),e[i].v=read(),e[i].c=read();
        S=0,T=(N+t)*N+1;
        InsertEdge(S,1,t);
        for (int i=1; i<=N+t; i++)
            {
                for (int j=2; j<=cnt; j++) edge[j].cap=edge[j].old;
                for (int j=1; j<=M; j++) InsertEdge(id(i-1,e[j].u),id(i,e[j].v),e[j].c);
                for (int j=1; j<=N; j++) InsertEdge(id(i-1,j),id(i,j),INF);
                InsertEdge(id(i,N),T,INF);
                int flow=Dinic(); if (flow==t) {printf("%d
    ",i); return 0;}
            }
        return 0;
    }
  • 相关阅读:
    2021年中国DevOps现状调查报告发布!
    带你看清梦饷集团如何成为上海在线新经济四小龙
    AI论文解读丨融合视觉、语义、关系多模态信息的文档版面分析架构VSR
    云图说 | 华为云医疗智能体,智联大健康,AI药物研发
    带你走进“华为链”
    初学者入门知识图谱必看的能力:推理
    带你探索CPU调度的奥秘
    鸿蒙轻内核定时器Swtmr:不受硬件和数量限制,满足用户需求
    FLINK基础(137):DS流与表转换(3) Handling of (Insert-Only) Streams(2)fromDataStream(FLINK1.13以上)
    FLINK基础(136):DS流与表转换(2) Handling of (Insert-Only) Streams(1)简介(FLINK1.13以上)
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5985139.html
Copyright © 2011-2022 走看看