最大联通子数组

#include<iostream>
#define N 100
#include<ctime>
using namespace std;

typedef struct
{
    int dian[N];
    int xian[N][N];
    int dianx,xianx;
}A;

void set(A &shu,int x,int y)//xy分别是行数和列数
{
    shu.dianx=x*y;
    srand((unsigned)time(NULL));
    for(int i=1;i<=shu.dianx;i++)
    {
        shu.dian[i]=rand()%10;
        if(rand()%2==1)
            shu.dian[i]=shu.dian[i]*(-1);
    }//////////////////////////////////////////////////////随机生成数组的数
    for(int i=1;i<=shu.dianx;i+=y)
    {
        for(int j=i;j<=i+y-2;j++)
        {
            shu.xian[j][j+1]=1;
            shu.xian[j+1][j]=1;
        }
    }
    for(int i=1+y;i<shu.dianx;i+=y)
    {
        for(int j=i;j<=i+x-1;j++)
        {
            shu.xian[j][j-y]=1;
            shu.xian[j-y][j]=1;
        }
    }////////////////////////////////////////////////////将随机生成的一维数组转换成二维的图的形式
}
void output(A shu)
{
    for(int i=1;i<=shu.dianx;i++)
    {
        cout<<"("<<shu.dian[i]<<")";
        if(shu.xian[i][i+1]==1)
            cout<<"--";
        else 
            cout<<endl;
    }
}////////////////////////////////////////////////////////图输出

/*void bianli(A &shu,int v,int visit[],int &b,int &max)
{
    visit[v]=1;

    b+=shu.dian[v];
    if(max<=b)
        max=b;

    for(int w=1;w<=shu.dianx;w++)
    {
        if((visit[w]==0)&&(shu.xian[v][w]==1))
        {
            if(b+shu.dian[w]<0)
            {
                shu.xian[v][w]=0;
            }
            else
                bianli(shu,w,visit,b,max);
        }
    }
}
*////////////////////////////////////////////////////////遍历

/*int select(A shu,int fir,int sec,int visit[],int x)
{
    int a,b;
    for(int w=1;w<=shu.dianx;w++)
    {
        if((visit[w]==0)&&(shu.xian[fir][w]==1))
        {
            a=shu.dian[w];break;
        }
    }
    for(int w=1;w<=shu.dianx;w++)
    {
        if((visit[w]==0)&&(shu.xian[sec][w]==1))
        {
            b=shu.dian[w];break;
        }
    }
    for(int w=1;w<=shu.dianx;w++)
    {
        if((visit[w]==0)&&(shu.xian[fir][w]==1)&&(shu.dian[w]>a))
        {
            a=shu.dian[w];
        }
    }
    for(int w=1;w<=shu.dianx;w++)
    {
        if((visit[w]==0)&&(shu.xian[sec][w]==1)&&(shu.dian[w]>b))
        {
            b=shu.dian[w];
        }
    }
    if(a>b)
        return fir;
    else
        return sec;
}*/////////////////////////////////////////////////////当两个链接点的值相等时,判断谁周围的最大值大
void bianli(A &shu,int v,int visit[],int &b,int &max,int x)
{
    visit[v]=1;

    max+=shu.dian[v];
    if(max>=b)
        b=max;

    int a=0,bo=0;
    for(int w=1;w<=shu.dianx;w++)
    {
        for(int c=1;c<=shu.dianx;c++)
        {
            if((visit[w]==0)&&(shu.xian[c][w]==1)&&(visit[c]==1))
            {
                a=w;bo=1;break;
            }
        }
        if(bo==1)
            break;
    }
    for(int w=1;w<=shu.dianx;w++)
    {
        for(int c=1;c<=shu.dianx;c++)
        {
            if((visit[w]==0)&&(shu.xian[c][w]==1)&&(visit[c]==1))
            {
                if(shu.dian[a]<shu.dian[w])
                    a=w;
                /*else if((shu.dian[a]==shu.dian[w])&&(a!=w))
                    a=select(shu,a,w, visit, x);*/
            }
        }
    }
    if(b+shu.dian[a]<0)
    {
        shu.xian[v][a]=0;
    }
    else
        bianli(shu,a,visit,b,max,x);
}
////////////////////////////////////////////////////////遍历

int NoVisit(int visit[],A shu)
{
    int k=0,i;
    for(i=1;i<=shu.dianx;i++)
    {
        if(visit[i]==0)
        {    
            k=i;
            break;
        }
    }
    return k;
}///////////////////////////////////判断图中没有visit的项

int main()
{
    cout<<"请输入数组行列数:"<<endl;
    int x,y;
    cin>>x>>y;
    A shu;
    set(shu,x,y);
    output(shu);

    int v=1,b[N]={0},h=0;
/*    while(v)
    {
        bianli(shu,v,visit,b[h],max);
        v=NoVisit(visit,shu);
        h++;
        if(shu.dian[v]<0)
        {
            visit[v]=1;
            b[h]=shu.dian[v];
            h++;
        }
    }
*/
    for(int i=1;i<=shu.dianx;i++)
    {
        if(shu.dian[i]<0)
        {
            b[i]=shu.dian[i];
        }
        else
        {
            int visit[N]={0};
            int max=0;
            bianli(shu,i,visit,b[i],max,x);
        }
    }

    int max=b[1];
    for(int i=2;i<=shu.dianx;i++)
    {
        if(b[i]>max)
            max=b[i];
    }
    cout<<"最大联通子数组的和为:"<<max<<endl;
}


思路:将二维矩阵转换成图的形式,即相邻两个数之间是联通的,记长度为1;根据图的遍历,将整个图从每个点都开始遍历一遍,便利时,当和小于0时断开两点间的路,当和大于最大和时最大和更新,这样,取以每个点为起点遍历的和的最大值即时最大联通子数组的和。遍历时,选取已遍历的联通子数组周围最大值遍历。还不能输出子数组。

感悟:老师上课举了一个思路,但是因为自己有自己的思路,所以没有按照老师的思路走,想试一试看能不能成功,事实是没有在规定的时间内完成任务。打算按照老师的方法再做一个,过几天再发吧。。。。

原文地址:https://www.cnblogs.com/xiangwo/p/4469471.html