无向图的最大割问题

问题描述:

给定一个无向图 G=(V,E),设 UV 是 G 的顶点集。对任意(u,v)∈E,若有 u∈U 且 v∈V-U,就称(u,v)为关于顶点集 U 的一条割边。顶点集 U 的所有割边构成图 G 的一个割。

G 的最大割是指 G 中所含边数最多的割。

使用回溯法,无剪枝函数设计,到达叶节点后,比较目前解和当前已知最优解,若更优,更新最优解和结点是否加入U顶点集。目前解通过一个for二重循环,如果两个结点有边相连,且属于不同的顶点集,即cut[i] != cut[j],割边数加1。

cut[i] = 0表示i结点不在U中,1表示在U中。

AC代码

#include<iostream>
#include<cstring>
using namespace std;

#define MAX_NODE 999    //最大顶点数+1

int max_cut=0;
int n,m;
int cut_pos[MAX_NODE];
void cal_max_cut(int n,int m,bool is_connected[][MAX_NODE],int cut[],int i)
{
    if(i==n+1)
    {
        int count=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(is_connected[i][j] && cut[i]!=cut[j])
                    count++;
            }
        }
        if(count>max_cut)
        {
            max_cut=count;
            for(int i=1;i<=n;i++)
            {
                if(cut[i] == 2)
                {
                    cut_pos[i]=0;
                    continue;
                }
                cut_pos[i]=cut[i];
            }
        }
        return;
    }
    cut[i]=1;
    cal_max_cut(n,m,is_connected,cut,i+1);
    cut[i]=2;
    cal_max_cut(n,m,is_connected,cut,i+1);
}

int main()
{
    cin>>n>>m;
    bool is_connected[MAX_NODE][MAX_NODE];
    memset(is_connected,false,sizeof(is_connected));
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        is_connected[x][y]=true;
        is_connected[y][x]=true;
    }
    int cut[n+1];
    memset(cut,0,sizeof(cut));
    cal_max_cut(n,m,is_connected,cut,1);
    cout<<max_cut<<endl;
    for(int i=1;i<=n;i++)
        cout<<cut_pos[i]<<" ";
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值