bzoj thousand questions plan 322: bzoj2561: minimum spanning tree (minimum cut)

https://www.lydsy.com/JudgeOnline/problem.php?id=2561

 

Consider the process of Kruscal's algorithm to find the minimum spanning tree

If the edge of length L between u and v can appear in the minimum spanning tree, it means that u and v are connected when the edge < L cannot

That is, when there are only edges <L in the graph, the minimum cut of u and v

If the edge of length L between u and v can appear in the maximum spanning tree, it means that u and v are connected when the edge > L cannot

That is, when there are only edges > L in the graph, the minimum cut of u and v

 

#include<cstdio>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
 
using namespace std;
 
#define N 20001
#define M 200001
 
int n,m;
 
int tot;
int src,decc;
int front[N],to[M<<1],nxt[M<<1],cap[M<<1];
 
int lev[N],cur[N];
queue<int>q;
 
struct node
{
    int u, v, l;
}e[M];
 
void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}
 
bool bfs()
{
        for(int i=0;i<=n;++i) cur[i]=front[i],lev[i]=-1;
        while(!q.empty()) q.pop();
        q.push(src);
        lev[src]=0;
        int now,t;
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            for(int i=front[now];i;i=nxt[i])
            {
                t=to[i];
                if(lev[t]==-1 && cap[i])
                {
                    lev[t]=lev[now]+1;
                    if(t==decc) return true;
                    q.push(t);
                }
            }
        }
        return false;
}
 
int dinic(int now,int flow)
{
        if(now==decc) return flow;
        int rest=0,delta;
        for(int &i=cur[now];i;i=nxt[i])
        if(cap[i] && lev[to[i]]==lev[now]+1)
        {
            delta=dinic(to[i],min(flow-rest,cap[i]));
            if(delta)
            {
                rest+=delta; 
                cap[i]-=delta; cap[i^1]+=delta;
                if(rest==flow) break;
            }
        }
        if(rest!=flow) lev[now]=-1;
        return rest;
}
 
bool cmp1(node p,node q)
{
    return p.l<q.l;
}
 
bool cmp2(node p,node q)
{
    return p.l>q.l;
}
 
void add(int u,int v,int w)
{
    to [ ++ tot] = v; nxt [tot] = front [u]; front [u] = tot; none [ w];
    to [ ++ tot] = u; nxt [tot] = front [v]; front [v] = tot; none [ w];
}
 
intmain ()
{
    read(n); read(m);
    for(int i=1;i<=m;++i) read(e[i].u),read(e[i].v),read(e[i].l);    
    read(src); read(decc);
    int L;
    read(L);
    int ans= 0 ;
    to = 1 ;
    sort(e+1,e+m+1,cmp1);
    for(int i=1;i<=m;++i)
        if(e[i].l>=L) break;
        else add(e[i].u,e[i].v,1);
    while(bfs()) ans+=dinic(src,2e9);
    memset(front,0,sizeof(front));
    to = 1 ;
    sort(e+1,e+m+1,cmp2);
    for(int i=1;i<=m;++i)
        if(e[i].l<=L) break;
        else add(e[i].u,e[i].v,1);
    while(bfs()) ans+=dinic(src,2e9);
    printf("%d",ans);
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325296716&siteId=291194637