csu1116(排列后prim)

本文探讨了一道经典的图论问题:如何在预算有限的情况下修复道路,以使与首都连通的城市的价值总和达到最大。文章提供了一种通过枚举和Prim算法结合的解决方案,并附带完整的C++实现代码。

题意:

有一幅双向图连接N个城市(标号1~n,1表示首都)  每个城市有一个价值W.

地震摧毁了所有道路,现给出可修复的m条道路并给出修复每条道路所需的费用

问在总费用不超过k的情况下,使得  与  首都连通的所有城市  的价值和 最大



解题思路:

点的数量不超过16 ,2^16次方枚举所有城市是否在连通的集合类

再通过prim判断这个集合是否合法即可


坑的是输入路径时可能会出现同样的点多次输出,要取最小的那个



#include <iostream>

#include <algorithm>

#include <string.h>

#define imax 1005

using namespacestd;

int n,m,k,maxn;

int po[20],map[20][20];

int pi[20];

int lowcost[20],s[20],u;

int prim()

{

    int sum=0,polu=0;

    for(int j=1;j<=n;j++)

        lowcost[j]=map[1][j];

    memset(s,0,sizeof(s));

    s[1]=1;

    for(int i=1;i<=n;i++)

    {

        int minn=imax;

        for(int j=1;j<=n;j++)

        {

            if(s[j]==0&&minn>lowcost[j]&&pi[j]==1)

            {

                minn=lowcost[j];

                u=j;

            }

        }

        if(minn==imax)

            break;

        

        s[u]=1;

        polu+=po[u];

        sum=sum+lowcost[u];

        for(int j=1;j<=n;j++)

        {

            if(lowcost[j]>map[u][j]&&pi[j]==1)

                lowcost[j]=map[u][j];

        }

    }

    if(sum<=k)

        return polu;

    else

        return -1;

}

void pai(int ans,int kk,int d)

{

    if(ans>kk)

    {

        int polu=prim();

        if(polu!=-1)

            maxn=max(maxn,polu);

        return;

    }

    for(int i=2;i<=n;i++)

    {

        if(i>d)

        {

            pi[i]=1;

            pai(ans+1,kk,i);

            pi[i]=0;

        }

        

    }

}

int main()

{

    int t,u,v,c;

    cin>>t;

    while(t--)

    {

        scanf("%d %d %d",&n,&m,&k);

        for(int i=1;i<=n;i++)

            scanf("%d",&po[i]);

        memset(map,0x3f,sizeof(map));

        for(int i=0;i<m;i++)

        {

            scanf("%d %d %d",&u,&v,&c);

            if(c<map[u][v])

                map[u][v]=map[v][u]=c;

        }

        memset(pi,0,sizeof(pi));

        pi[1]=1;

        maxn=0;

        for(int kk=2;kk<=n;kk++)

        {

            pai(2,kk,1);

            //printf("********\n");

        }

        cout<<maxn+po[1]<<endl;

    }

    return0;

}


**************************


前男友联系了我,这几天有点心神不定

曾经的大男孩现在心事有点重,我不知道他喜不喜欢现在的生活,感觉有些疲惫的样子

他已经有了未婚妻,想来要是我在他身边,恐怕也不能让他变得轻松,因为我没有办法在他身边安稳地陪着他

希望他身边的那个人可以给他带来他真正想要的生活


乐播投屏是一款简单好用、功能强大的专业投屏软件,支持手机投屏电视、手机投电脑、电脑投电视等多种投屏方式。 多端兼容与跨网投屏:支持手机、平板、电脑等多种设备之间的自由组合投屏,且无需连接 WiFi,通过跨屏技术打破网络限制,扫一扫即可投屏。 广泛的应用支持:支持 10000+APP 投屏,包括综合视频、网盘与浏览器、美韩剧、斗鱼、虎牙等直播平台,还能将央视、湖南卫视等各大卫视的直播内容一键投屏。 高清流畅投屏体验:腾讯独家智能音画调校技术,支持 4K 高清画质、240Hz 超高帧率,低延迟不卡顿,能为用户提供更高清、流畅的视觉享受。 会议办公功能强大:拥有全球唯一的 “超级投屏空间”,扫码即投,无需安装。支持多人共享投屏、远程协作批注,PPT、Excel、视频等文件都能流畅展示,还具备企业级安全加密,保障会议资料不泄露。 多人互动功能:支持多人投屏,邀请好友加入投屏互动,远程也可加入。同时具备一屏多显、语音互动功能,支持多人连麦,实时语音交流。 文件支持全面:支持 PPT、PDF、Word、Excel 等办公文件,以及视频、图片等多种类型文件的投屏,还支持网盘直投,无需下载和转格式。 特色功能丰富:投屏时可同步录制投屏画面,部分版本还支持通过触控屏或电视端外接鼠标反控电脑,以及在投屏过程中用画笔实时标注等功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值