2012年湖南省第八届大学生计算机程序设计竞赛 F 题 Kingdoms
2014-05-11 13:21
316 查看
题目大意:
给你n个城市,m条道路,每个城市有P【i】个人,每条道路都有一个COST,要求总COST不超过K的情况下,使得连接城市的人口最多且必须包括第一个城市
因为N最大为16且第一个城市必被选择,所以只需枚举剩下N-1个城市的状态即可,枚举每个状态的时候,求出目前的最小生成树的COST,若COST小于K,则更新ans
这题我知道怎么写之后一直没写对,今天终于找出错误了,感觉自己太傻吊了。。。
错误: 在求最小生成树时,我用hash【】去记录那些点已被加入到最小生成树中, 然后根据hash算出当前状态的总人口,这样就会在城市1没有加入到最小生成树的时候,
ans也更新了
AC代码:
之前WA的代码:
测试数据
3
4 1 3
100 200 300 400
3 4 1
输出
800
原因就是枚举状态110的时候, ans也更新了。。。
给你n个城市,m条道路,每个城市有P【i】个人,每条道路都有一个COST,要求总COST不超过K的情况下,使得连接城市的人口最多且必须包括第一个城市
因为N最大为16且第一个城市必被选择,所以只需枚举剩下N-1个城市的状态即可,枚举每个状态的时候,求出目前的最小生成树的COST,若COST小于K,则更新ans
这题我知道怎么写之后一直没写对,今天终于找出错误了,感觉自己太傻吊了。。。
错误: 在求最小生成树时,我用hash【】去记录那些点已被加入到最小生成树中, 然后根据hash算出当前状态的总人口,这样就会在城市1没有加入到最小生成树的时候,
ans也更新了
AC代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; struct node { int x,y,c; }edge[202],a[202]; int n, m, k; int Father[20]; int p[20]; int vis[20]; // 标记改点是否选择 //int hash[20]; int cmp(node x, node y) { return x.c< y.c; } int find(int x) { return x == Father[x]? x : Father[x]= find(Father[x]); } int dij(int nn,int mm) { //memset(hash, 0, sizeof(hash)); for(int i= 0; i< n; i++) Father[i]= i; sort(a+1, a+mm+1, cmp); int ans= 0; int bian= 1, dian= 1; while(dian<= nn-1 &&bian<= mm) { int vf1= find(a[bian].x); int vf2= find(a[bian].y); if(vf1!= vf2) { //hash[a[bian].x]= 1; // hash[a[bian].y]= 1; dian++; ans+= a[bian].c; Father[vf2]= vf1; } bian++; } if(dian == nn) return ans; else return 10000000; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d %d",&n,&m,&k); for(int i= 1; i<= n; i++) scanf("%d",&p[i-1]); for(int i= 1; i<= m; i++) { int a,b, num; scanf("%d %d %d",&a,&b,&num); edge[i]= (node){a-1, b-1, num}; } int ans= 0; for(int S= 0; S< (1<<(n-1)); S++) //第一点必选,枚举剩下的n-1个点的状态 { int sumn= 1; int summ= 0; memset(vis, 0, sizeof(vis)); vis[0]= 1; for(int i= 0; i< n-1; i++) if(S & (1<< i)) //若选择第i+1个城市, 城市的标号为0-(N-1) { vis[i+1]= 1; sumn++; } for(int i= 1; i<= m; i++) if(vis[edge[i].x] && vis[edge[i].y]) { summ++; a[summ]= (node){edge[i].x, edge[i].y, edge[i].c}; } int cost= dij(sumn, summ); int xixi= p[0]; if(cost<= k) { for(int i= 1; i< n; i++) if(vis[i]) //之前这里用hash标记然后判断hash[i],最后发现当最小生成树中不包括点0时也会更新ans xixi+= p[i]; if(xixi> ans) ans= xixi; } } printf("%d\n",ans); } return 0; }
之前WA的代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; struct node { int x,y,c; }edge[202],a[202]; int n, m, k; int Father[20]; int p[20]; int vis[20]; // 标记改点是否选择 int hash[20]; int cmp(node x, node y) { return x.c< y.c; } int find(int x) { return x == Father[x]? x : Father[x]= find(Father[x]); } int dij(int nn,int mm) { memset(hash, 0, sizeof(hash)); for(int i= 0; i< n; i++) Father[i]= i; sort(a+1, a+mm+1, cmp); int ans= 0; int bian= 1, dian= 1; while(dian<= nn-1 &&bian<= mm) { int vf1= find(a[bian].x); int vf2= find(a[bian].y); if(vf1!= vf2) { hash[a[bian].x]= 1; hash[a[bian].y]= 1; dian++; ans+= a[bian].c; Father[vf2]= vf1; } bian++; } return ans; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d %d",&n,&m,&k); for(int i= 1; i<= n; i++) scanf("%d",&p[i-1]); for(int i= 1; i<= m; i++) { int a,b, num; scanf("%d %d %d",&a,&b,&num); edge[i]= (node){a-1, b-1, num}; } int ans= 0; for(int S= 0; S< (1<<(n-1)); S++) //第一点必选,枚举剩下的n-1个点的状态 { int sumn= 1; int summ= 0; memset(vis, 0, sizeof(vis)); vis[0]= 1; for(int i= 0; i< n-1; i++) if(S & (1<< i)) //若选择第i+1个点 { vis[i+1]= 1; sumn++; } for(int i= 1; i<= m; i++) { if(vis[edge[i].x] && vis[edge[i].y]) { summ++; a[summ]= (node){edge[i].x, edge[i].y, edge[i].c}; } } int cost= dij(sumn, summ); int xixi= p[0]; if(cost<= k) { for(int i= 1; i< n; i++) if(hash[i]) { xixi+= p[i]; } if(xixi> ans) ans= xixi; } } printf("%d\n",ans); } return 0; }
测试数据
3
4 1 3
100 200 300 400
3 4 1
输出
800
原因就是枚举状态110的时候, ans也更新了。。。
相关文章推荐
- 数据结构的Java实现——顺序表
- 【网络基础】子网划分、基于子网掩码的分组转发
- 数据结构 --- 单链表
- 题目1018:统计同成绩学生人数(哈希算法,2006年浙江大学计算机及软件工程研究生机试真题)
- Adnroid 检测手机网络 和 wifi 是否存在
- Linux环境编程之文件I/O(四):文件I/O的数据结构
- http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed wit
- 图论-三边路径
- 数据结构之图的深度优先搜索
- 数据结构
- POJ 1149 PIGS 网络流Dinic
- POJ 1149 PIGS 网络流Dinic
- TCP/IP之协议关系与结构
- 使用CoreTelephony获得SIM卡网络运营商名称
- 黑马程序员 ---------- Java网络技术之 ---正则表达式 (Day06)
- android网络抓包及Wireshark介绍
- 使用ssh开发rest web服务支持http etag header的教程详解
- 数据结构 DFS
- 邻接矩阵 数据结构
- UVA 297 Quadtrees( 数据结构,树)