hdu 2489 Minimal Ratio Tree【Dfs+kruskal】
2016-05-16 16:48
323 查看
Minimal Ratio Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3928 Accepted Submission(s): 1207
Problem Description
For a tree, which nodes and edges are all weighted, the ratio of it is calculated according to the following equation.
Given a complete graph of n nodes with all nodes and edges weighted, your task is to find a tree, which is a sub-graph of the original graph, with m nodes and whose ratio is the smallest among all the trees of m nodes in the graph.
Input
Input contains multiple test cases. The first line of each test case contains two integers n (2<=n<=15) and m (2<=m<=n), which stands for the number of nodes in the graph and the number of nodes in the minimal ratio tree. Two zeros end the input. The next
line contains n numbers which stand for the weight of each node. The following n lines contain a diagonally symmetrical n×n connectivity matrix with each element shows the weight of the edge connecting one node with another. Of course, the diagonal will be
all 0, since there is no edge connecting a node with itself.
All the weights of both nodes and edges (except for the ones on the diagonal of the matrix) are integers and in the range of [1, 100].
The figure below illustrates the first test case in sample input. Node 1 and Node 3 form the minimal ratio tree.
Output
For each test case output one line contains a sequence of the m nodes which constructs the minimal ratio tree. Nodes should be arranged in ascending order. If there are several such sequences, pick the one which has the smallest node number; if there's a
tie, look at the second smallest node number, etc. Please note that the nodes are numbered from 1 .
Sample Input
3 2
30 20 10
0 6 2
6 0 3
2 3 0
2 2
1 1
0 2
2 0
0 0
Sample Output
1 3
1 2
思路:
因为n比较小,所以我们可以采取直接暴力Dfs枚举所有可能选取的点的方案,然后累加点权值,然后将这些点相关的边加入数组中,贪心求最小生成树即可。
注意的点:我们在Dfs的时候,如果每一层都遍历n个点,是会超时的,所以我们枚举当前点是否加入子图中,这样就变成了每层枚举两个操作,防止超时的情况。
AC代码:
#include<string.h> #include<algorithm> #include<stdio.h> using namespace std; struct zuobiao { int x,y,w; }a[121212]; int d[250]; int map[250][250]; int f[250]; int vis[250]; int output[250]; int n,m; double minn; int cmp(zuobiao a,zuobiao b) { return a.w<b.w; } int find(int a) { int r=a; while(f[r]!=r) r=f[r]; int i=a; int j; while(i!=r) { j=f[i]; f[i]=r; i=j; } return r; } void merge(int a,int b) { int A,B; A=find(a); B=find(b); if(A!=B) f[B]=A; } void solve(int sumd) { int tot=0,sume=0; for(int i=0;i<n;i++) { f[i]=i; } for(int i=0;i<n;i++) { if(vis[i]==1) { for(int j=0;j<n;j++) { if(vis[j]==0)continue; if(map[i][j]==0)continue; a[tot].x=i; a[tot].y=j; a[tot].w=map[i][j]; tot++; } } } sort(a,a+tot,cmp); for(int i=0;i<tot;i++) { if(find(a[i].x)!=find(a[i].y)) { merge(a[i].x,a[i].y); sume+=a[i].w; } } int tot2=0; double out=sume*1.0/sumd; if(out<minn||minn==-1) { minn=out; for(int i=0;i<n;i++) { if(vis[i]==1) output[tot2++]=i; } } } void Dfs(int cont,int now,int sumd) { if(now>n)return ; if(cont==m) { solve(sumd); return ; } vis[now]=1; Dfs(cont+1,now+1,sumd+d[now]); vis[now]=0; Dfs(cont,now+1,sumd); } int main() { while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; for(int i=0;i<n;i++) { scanf("%d",&d[i]); } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&map[i][j]); } } int ans[25]; memset(vis,0,sizeof(vis)); minn=-1; Dfs(0,0,0); for(int i=0;i<m;i++) { if(i==0) printf("%d",output[i]+1); else printf(" %d",output[i]+1); } printf("\n"); } } /* 3 2 30 10 20 0 3 1 3 0 1 1 1 0 //////1 3 3 2 30 30 10 0 3 1 3 0 1 1 1 0 //////1 3 3 2 30 80 10 0 3 1 3 0 1 1 1 0 //////2 3 */
相关文章推荐
- 灰帽子Python 学习记录 6
- 国内计算机期刊
- 安卓汉字转拼音字符串,进行模糊搜索时使用
- 备忘录AIX主机下用SHELL脚本编写FTP传某个目录下的文件到LINUX主机
- 在Windows下搭建React Native Android开发环境
- Android Launcher 自定义View 炫酷换壁纸效果,水瓶加水进度显示效果
- 建表 相关
- part1:12-sudo用户管理和Linux密码故障排除
- tomcat编译乱码问题
- 快速为所有数组元素赋相同的值以及在switch中的应用
- 使用工具
- Hibernate写hql语句与不写hql语句的区别?
- 计算机期刊
- log4j按天生成日志文件
- MYSQL中INET_ATON(expr)函数的调查
- ViewPager实现炫酷的滑动缩放广告页
- 为什么object_getClass(obj)与[OBJ class]返回的指针不同
- 欧拉函数模版
- GCD 的理解
- android坐标