EOJ Monthly 2020.3 maze (Fig hierarchical thinking)

Title: https://acm.ecnu.edu.cn/contest/255/problem/A/

Meaning of the questions: There are personal point T m at the point S, should all go, the number of each channel can only be given away everyday questions, ask at least a few days to complete.

Analysis: This is the largest water flow problems are very similar, except that the maximum water flow is always will account for this one channel, but here only occupy a unit of time;

   We consider half the number of days, because the more the number of days, the greater the likelihood can all go to the end, it is monotone. Then the number of days based on two points, into the n-layer of FIG., The number of days even neighboring node adjacent edges, it is determined whether the maximum flow can be satisfied.

#include<bits/stdc++.h>
using namespace std;
const int M=4e5+5;
const int N=5500;
const int inf=0x3f3f3f3f;
int tot,s,t;
struct node{
    int u,v,nextt;
    int w;
}e[M<<1];
vector<node>g[M];
int head[N],deep[N],cur[N];
void addedge(int u,int v,int w){
    e[tot].v=v;
    e[tot].w=w;
    e[tot].nextt=head[u];
    head[u]=tot++;
    e[tot].v=u;
    e[tot].w=0;
    e[tot].nextt=head[v];
    head[v]=tot++;
}
bool bfs(){
    for(int i=0;i<=t;i++)
        deep[i]=0;
    queue<int>que;
    que.push(s);
    deep[s]=1;
    while(!que.empty()){
        int u=que.front();
        que.pop();
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(e[i].w>0&&deep[v]==0){
                deep[v]=deep[u]+1;
                if(v==t)
                    return true;
                que.push(v);
            }
        }
    }
    return deep[t]!=0;
}
int dfs(int u,int fl){
    if(u==t)
        return fl;
    int ans=0,x=0;
    for(int i=cur[u];~i;i=e[i].nextt){
        int v=e[i].v;
        if(e[i].w>0&&deep[v]==deep[u]+1){
            x=dfs(v,min(fl-ans,e[i].w));
            e[i].w-=x;
            e[i^1].w+=x;
            ans+=x;
            if(ans==fl)
                return ans;
            if(e[i].w)
                cur[u]=i;

        }
    }
    if(ans==0)
        deep[u]=0;
    return ans;
}
int dinic(){
    int res=0;
    while(bfs()){

        for(int i=0;i<=t;i++)
            cur[i]=head[i];
        res+=dfs(s,inf);
    }
    return res;
}
int main(){
    int num,n,m,S,T,minn=0;
    scanf("%d%d%d%d%d",&num,&n,&m,&S,&T);
    for(int u,v,w,i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        g[u].push_back(node{u,v,0,w});
    }


    int l=1,r=100;
    while(l<=r){
        int x=(l+r)>>1;
 ///       cout<<x<<"!!"<<endl;
        tot=0;
        s=S,t=T+x*n;
        memset(head,-1,sizeof(head));
        for(int i=1;i<=n;i++)
            for(auto pv:g[i]){
                int u=pv.u,v=pv.v,w=pv.w;
                for(int j=1;j<=x;j++)
                    addedge(u+(j-1)*n,v+j*n,w);
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=x;j++)
                addedge(i+(j-1)*n,i+j*n,inf);
        if(dinic()>=num)
            minn=x,r=x-1;
        else
            l=x+1;
    }
    printf("%d\n",minn);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/starve/p/12590467.html