地震逃生

一、题目

老师们立刻带领 x 名学生逃跑,整个学校可以抽象地看成一个有向图.

图中有 n 个点,m 条边。1 号点为教室,n 号点为安全地带,每条边都只能容纳一定量的学生,超过楼就要倒塌,由于人数太多,校长决定让同学们分成几批逃生.

只有第一批学生全部逃生完毕后,第二批学生才能从 1 号点出发逃生,现在请你帮校长算算,每批最多能运出多少个学生,x 名学生分几批才能运完。

第一行三个整数n,m,x;

以下 m 行,每行三个整数a,b,c(1a,bn,0cx)描述一条边,分别代表从 a 点到 b 点有一条边,且可容纳 c 名学生。

两个整数,分别表示每批最多能运出多少个学生,x 名学生分几批才能运完。如果无法到达目的地(n 号点)则输出 Orz Ni Jinan Saint Cow!

二、思路

dinic 算法写好,算出每次最多几个人,然后除x就行了。

三、代码

复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=2009;
struct edge{int to,nxt,w;}e[N*2];int hd[N],tot=1;
void add(int u,int v,int w){
    e[++tot]=(edge){v,hd[u],w}; hd[u]=tot;
}

int n,m,d[N],ans,x;
bool bfs(){
    queue<int>q; memset(d,0,sizeof(d));
    q.push(1),d[1]=1;
    while(!q.empty()){
        int u=q.front(); q.pop();
        for(int i=hd[u],v;i;i=e[i].nxt)
            if(!d[v=e[i].to]&&e[i].w){
                q.push(v),d[v]=d[u]+1;
                if(v==n) return 1;
            }
    }
    return 0;
} 
int dfs(int u,int flow){
    if(u==n) return flow;
    int rest=flow;
    for(int i=hd[u],v;i&&rest;i=e[i].nxt){
        if(e[i].w&&d[v=e[i].to]==d[u]+1){
            int tmp=dfs(v,min(rest,e[i].w));
            if(!tmp) d[v]=0;
            rest-=tmp; e[i].w-=tmp; e[i^1].w+=tmp;
        }
    }
    return flow-rest; //真正给出去的 
}

int main(){
    scanf("%d%d%d",&n,&m,&x);
    for(int i=1,u,v,w;i<=m;i++)
        scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,0);
    int tmp=0;
    while(bfs()) while(tmp=dfs(1,1e9)) ans+=tmp;
    if(!ans){puts("Orz Ni Jinan Saint Cow!");return 0;} 
    printf("%d ",ans);
    int a2=ceil(x*1./ans);
    printf("%d",a2);
    return 0;
}
复制代码

四、分析

时间复杂度:O(n2m),一般能够处理104~105规模的网络

n点的个数,m有向边的个数

 

posted @   ImreW  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示