UVA-10480 Sabotage (Minimum cut of network flow)

The meaning of the question : source point 1, sink point 2, undirected edges, let those edges to be minimum cut

Ideas:

Run it with dinic, then check the edges together, and finally find the edge with the smallest cut, which also needs to run on both sides according to whether the edge is 0, which feels very troublesome.

But looking at other people's problem solutions, I found that you can run bfs directly on the last side. When the broken side is the smallest cut, it still feels very good. In addition, because the data is small, ek can also run over.

Code:

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int maxn=50+10;
const int maxm=1e3+10;
const int inf=0x3f3f3f3f;
typedef pair<int,int>pii;
struct tri{int x,y,z;}edg[maxm];

int n,m,s,t;
int head[maxn],head2[maxn],dep[maxn];

int edg_cnt;
void addedg(int a,int b,int c)
{
    edg[edg_cnt]={b,c,head[a]};
    head[a]=edg_cnt++;
}
void addedgs(int a,int b,int c)
{
    addedg(a,b,c);
    addedg(b,a,c);
}

bool bfs()
{
    queue<int>q;
    q.push(s);
    memset(dep,0,sizeof(dep));
    dep[s]=1;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int i=head[u];~i;i=edg[i].z)
        {
            int v=edg[i].x;
            if(edg[i].y&&!dep[v])
            {
                q.push(v);
                dep[v]=dep[u]+1;
            }
        }
    }
    return dep[t];
}
int dfs(int u,int low)
{
    int ret=0;
    if(u==t||!low)return low;
    for(int &i=head2[u];~i;i=edg[i].z)
    {
        int v=edg[i].x;
        if(dep[v]==dep[u]+1&&edg[i].y)
        {
            int flow=dfs(v,min(low,edg[i].y));
            if(!flow)continue;
            edg[i].y-=flow;
            edg[i^1].y+=flow;
            low-=flow;
            ret+=flow;
            if(!low)break;
        }
    }
    return ret;
}
void dinic()
{
    s=1,t=2;
    while(bfs())
    {
        for(int i=1;i<=n;i++)head2[i]=head[i];
        dfs(s,inf);
    }
}

int father[maxn];
int ff(int a)
{
    if(a==father[a])return a;
    else return father[a]=ff(father[a]);
}

int main()
{
    // freopen("in.txt","r",stdin);
    while(1)
    {
        edg_cnt=0;
        scanf("%d%d",&n,&m);
        if(!n&&!m)break;
        for(int i=1;i<=n;i++)
        {
            father[i]=i;
            head[i]=-1;
        }
        while(m--)
        {
            int a,b,c;scanf("%d%d%d",&a,&b,&c);
            addedgs(a,b,c);
        }
        dinic();
        for(int i=0;i<edg_cnt;i+=2)
        {
            int a=edg[i].x,b=edg[i^1].x;
            if(edg[i].y&&edg[i^1].y)
            {
                int fa=ff(a),fb=ff(b);
                if(fa!=fb)
                {
                    if(fa>fb)swap(fa,fb);
                    father[fb]=fa;
                }
            }
        }
        for(int i=0;i<edg_cnt;i++)
        {
            int a=edg[i].x,b=edg[i^1].x;
            if(!edg[i].y)
            {
                int fa=ff(a),fb=ff(b);
                if(fa!=fb)
                {
                    if(fa>fb)swap(fa,fb);
                    if(fa==1&&fb==2)printf("%d %d\n",a,b);
                    else father[fb]=fa;
                }
            }
        }
        puts("");
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_43700916/article/details/104227159
Recommended