湖南省第八届省赛,最小生成树Prim算法+利用二进制的状态枚举
来源:互联网 发布:淘宝脏辫接发视频教程 编辑:程序博客网 时间:2024/06/15 11:41
题目信息:http://blog.csdn.net/acm_cxq/article/details/52192026
题意:
n个城市1--n,有m座桥可以城市,编号为1的城市是皇宫。修建每座桥的费用为c,每个城市的人口为pi。总费用为k。
求从皇宫出发,修建桥连接尽可能多的城市,城市相互直接或者间接连接通向皇宫,使得跟皇宫相连的所有城市的人口数之和为最大值,且费用不超过k。(无向图)
思路:巧妙运用二进制保存所有城市的状态,n个城市,每个城市选或不选,有2^n种可能。
1代表选,0代表不选。(1号城市必须入选)
如n等于4时,4个城市。
那么 1<<4等于16种可能,
如1101,代表第1,3,4城市入选,第二个城市不选。
然后将选入的城市的编号保存在一个数组里面,用prim算法求得入选城市相连后的花费。
在所有状态中,找出总人口最多的那个状态。
代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn = 20;const int INF = 999999999;int n;//城市,编号1--n,1为皇帝宫int m;//可以修的路int cost;//最大花费int weight[maxn];//每个城市对应的人口数int graph[maxn][maxn];//修建两个城市间路的费用int city[maxn];//被选的城市int state;//状态int COST,temp;//被选的城市的总人数int pos;//被选的城市个数void init() {for(int i=1; i<=n; i++) {for(int j=1; j<=n; j++) {graph[i][j] = INF;if(i==j) graph[i][j] = 0;}}}int prim(int n,int pos) {int mincost[maxn];bool used[maxn];for(int i=0; i<n; i++) {mincost[city[i]] = graph[city[i]][pos];used[city[i]] = false;}mincost[pos] = 0;int res = 0;while(true) {int v = -1;//从未被true的顶点中选取从已经选的点到其权值最小的顶点for(int u=0; u<n; u++) {if(!used[city[u]]&&(v==-1||mincost[city[u]]<mincost[city[v]])) v = u;}if(v==-1) break;//更新完了 used[city[v]] = true;res+=mincost[city[v]];if(res>cost) return -1;for(int u = 0; u<n; u++) {mincost[city[u]] = min(mincost[city[u]],graph[city[v]][city[u]]);}}return res;}int main() {int cases;cin>>cases;int a,b,c;while(cases--) {cin>>n>>m>>cost;memset(city,0,sizeof(city)); for(int i=1; i<=n; i++) {cin>>weight[i];}for(int i=0; i<m; i++) {cin>>a>>b>>c;graph[a][b] = graph[b][a] = min(graph[a][b],c);}state = 1<<n;//枚举2的n次方中可能性 COST = -1;for(int i = state-1; i>0; i--) {//第一个城市必须入选,不然就进入下一个状态if(!(i&1)) continue;//如果这些状态中第一个城市没有入选,那么直接跳过 pos = 0;temp = 0;for(int j=0; j<n; j++) {//判断哪些城市入选 if((i>>j)&1) {city[pos++] = j+1;//表示第j+1个城市入选temp += weight[j+1];//加上第j+1个城市的人口数}}int cost = prim(pos,city[0]);//以第一个城市到各个被选城市的最小花费 //如果总花费不大于给定的总价,选择总人数最多的方案 if(cost!=-1) {COST = max(COST,temp);if(i==state-1) break;//如果所有城市都入选,那人口总数必定是最大的!!!}}cout<<COST<<endl;}}
0 0
- 湖南省第八届省赛,最小生成树Prim算法+利用二进制的状态枚举
- 湖南省第八届省赛 kingdoms (生成树+枚举)
- UVa 10807 Prim(最小生成树+二进制枚举)
- Prim 算法生成的最小生成树
- 最小生成树的prim算法代码
- 最小生成树的prim算法实现
- 构造最小生成树的 prim 算法
- 最小生成树的Prim算法
- 图的最小生成树(prim算法)
- 最小生成树的prim算法
- 最小生成树的prim算法
- JAVA的最小生成树(prim)算法
- 最小生成树的prim算法实现
- 最小生成树的prim算法
- 最小生成树的Prim算法
- 最小生成树的Prim算法笔记
- 求最小生成树的Prim算法
- 最小生成树的prim算法
- 程序包javax.servlet不存在
- C语言 scanf在while循环里的无限循环
- PowerOj 1736(网络流—最大流)
- 【BFS】(一)抓住那头牛(poj 3278)
- Java IO流之【缓冲流和文件流复制文件对比】
- 湖南省第八届省赛,最小生成树Prim算法+利用二进制的状态枚举
- JVM学习笔记(八)类加载机制-类加载器
- 博客地址
- 囧字构造 模拟
- JVM源码分析之FinalReference完全解读
- 多线程之 synchronized 和 volatile
- Java反射八 数组
- Unreal Open Day 2017 参会总结——ACT(动作)游戏制作经验分享
- angular2权威教程(中文版)(ng-book2)