Sabotaje UVA-10480 (corte mínimo de flujo de red)

El significado de la pregunta : punto de origen 1, punto de hundimiento 2, bordes no dirigidos, deje que esos bordes se corten al mínimo

Ideas:

Ejecútelo con dinic, y luego verifique los bordes juntos, y finalmente encuentre el borde con el corte más pequeño, que también debe correr en ambos lados según si el borde es 0, lo que se siente muy problemático.

Pero al ver las soluciones a los problemas de otras personas, descubrí que se puede ejecutar bfs directamente en el último lado. Cuando el lado roto es el corte más pequeño, se siente muy bien. Además, debido a que los datos son pequeños, ek también puede sobrepasarse.

Código:

#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;
}

 

Supongo que te gusta

Origin blog.csdn.net/qq_43700916/article/details/104227159
Recomendado
Clasificación