BJ simulation cut [minimum cut tree]

Topic description:

There is an undirected graph with n points. Given the minimum cut between any two points, find a graph that meets the conditions.
n<=100

Problem solving ideas:

Each undirected graph corresponds to a minimum cut tree, and the minimum cut between any two points is the minimum edge between two points on the minimum cut tree. Now consider how to build this minimum cut tree.
In fact, it is the maximum spanning tree, because considering adding edges from large to small, if x and y are not in the same connected block, the optimal choice must be to connect edges between x and y.
Finally, judge whether each pair of points is satisfied.

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define pb push_back
using namespace std;
int getint()
{
    int i=0,f=1;char c;
    for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
    if(c=='-')c=getchar(),f=-1;
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}
const int N=105;
int n,m,a[N][N];
int tot,first[N],nxt[N<<1],to[N<<1],w[N<<1];
int dep[N],f[N],fa[N];
struct edge
{
    int x,y,w,bz;
    inline friend bool operator < (const edge &a,const edge &b){return a.w>b.w;}
}bian[N*N];
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void add(int x,int y,int z){nxt[++tot]=first[x],first[x]=tot,to[tot]=y,w[tot]=z;}
void kruskal()
{
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int x=bian[i].x,y=bian[i].y,fx=find(x),fy=find(y);
        if(fx!=fy)bian[i].bz=1,add(x,y,bian[i].w),add(y,x,bian[i].w),fa[fx]=fy;
    }
    for(int i=1;i<=n;i++)fa[i]=0;
}
void dfs(int u)
{
    for(int e=first[u];e;e=nxt[e])
    {
        int v=to[e];if(v==fa[u])continue;
        fa[v]=u,dep[v]=dep[u]+1,f[v]=w[e],dfs(v);
    }
}
int getmin(int x,int y)
{
    int res=1e9;
    while(x!=y)
    {
        if(dep[x]<dep[y])swap(x,y);
        res=min(res,f[x]),x=fa[x];
    }
    return res;
}
int main()
{
    //freopen("lx.in","r",stdin);
    n=getint();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)a[i][j]=getint();
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            if(a[i][j]!=a[j][i]){puts("-1");return 0;}
            ++m,bian[m].x=i,bian[m].y=j,bian[m].w=a[i][j];
        }
    sort(bian+1,bian+m+1);
    kruskal(),dfs(1);
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(getmin(i,j)!=a[i][j]){puts("-1");return 0;}
    cout<<n-1<<'\n';
    for(int i=1;i<=m;i++)
        if(bian[i].bz)cout<<bian[i].x<<' '<<bian[i].y<<' '<<bian[i].w<<'\n';
    return 0;
}

Guess you like

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