题意

汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边。1号点为教室,n号点为安全地带,每条边都只能容纳一定量的学生,超过楼就要倒塌,由于人数太多,校长决定让同学们分成几批逃生,只有第一批学生全部逃生完毕后,第二批学生才能从1号点出发逃生,现在请你帮校长算算,每批最多能运出多少个学生,x名学生分几批才能运完。

\(x<2^{31},n \leq 200,m \leq 2000\)

分析

都不用建模了,直接跑网络流就行了。

时间复杂度\(O(n^2 m)\)

代码

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#define co const
template<class T>T read(T&x)
{
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        data=data*10+ch-'0';
        ch=getchar();
    }
    return x=data*w;
}
using namespace std;
co int INF=0x3f3f3f3f;

co int MAXN=250,MAXM=2050;
int n,m;

struct edge
{
    int nx,to,c;
}e[MAXM<<1];
int head[MAXN],ecnt;

void addedge(int x,int y,int c)
{
    e[++ecnt].to=y,e[ecnt].c=c;
    e[ecnt].nx=head[x],head[x]=ecnt;
}

queue<int>Q;
int dep[MAXN],cur[MAXN];

bool bfs(int s,int t)
{
    copy(head+1,head+n+1,cur+1);
    fill(dep+1,dep+n+1,INF);
    dep[s]=0;
    Q.push(s);
    while(Q.size())
    {
        int x=Q.front();
        Q.pop();
        for(int i=head[x];i!=-1;i=e[i].nx)
        {
            int y=e[i].to,c=e[i].c;
            if(c>0&&dep[y]>dep[x]+1)
            {
                dep[y]=dep[x]+1;
                Q.push(y);
            }
        }
    }
    return dep[t]<INF;
}

int dfs(int x,int t,int lim)
{
    if(x==t||!lim)
        return lim;
    int delta=0,inc;
    for(int i=cur[x];i!=-1;i=e[i].nx)
    {
        cur[x]=i;
        int y=e[i].to,c=e[i].c;
        if(dep[y]==dep[x]+1&&(inc=dfs(y,t,min(lim,c))))
        {
            delta+=inc;
            lim-=inc;
            e[i].c-=inc;
            e[i^1].c+=inc;
            if(!lim) // edit 1
                break;
        }
    }
    return delta; // edit 2
}

int Dinic(int s,int t)
{
    int res=0;
    while(bfs(s,t))
        res+=dfs(s,t,INF);
    return res;
}

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int tot;
    read(n);read(m);read(tot);
    fill(head+1,head+n+1,-1);
    ecnt=-1;
    for(int i=1;i<=m;++i)
    {
        int x,y,c;
        read(x);read(y);read(c);
        addedge(x,y,c);
        addedge(y,x,0);
    }
    int ans=Dinic(1,n);
    if(ans==0)
    {
        puts("Orz Ni Jinan Saint Cow!");
    }
    else
    {
        printf("%d %d\n",ans,tot/ans+bool(tot%ans));
    }
    return 0;
}
05-11 00:29