【最小比例树】Minimal Ratio Tree
Minimal Ratio Tree
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3391 Accepted Submission(s): 1027
Problem Description
For a tree, which nodes and edges are all weighted, the ratio of it is calculated according to the following equation.
![](http://acm.hdu.edu.cn/data/images/con212-1005-1.JPG)
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.
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.
![](http://acm.hdu.edu.cn/data/images/con212-1005-2.JPG)
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个点的联通图中,找出M个点联通子图的最小比例生成树、
解法:(DFS+最小生成树):
View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <math.h> 5 #include <queue> 6 #define INF 1e9 7 #define EXP (1e-9) 8 #define MAX 200 9 using namespace std; 10 int Sign; 11 int First[MAX]; 12 int P_V[MAX];/*点权*/ 13 int P[MAX]; /*点记录*/ 14 int IDD[MAX];/*点标记*/ 15 int Map[MAX][MAX]; 16 int Min_P[MAX];/*记录答案坐标*/ 17 double Min_V,Vlue;/*记录最小比例*/ 18 int N,M; 19 struct Poin 20 { 21 int to,v,next; 22 friend bool operator<(Poin a,Poin b) 23 { 24 return a.v>b.v; 25 } 26 }ID[MAX*5]; 27 28 void Cread(int n){for(int i=0;i<=n;i++)First[i]=0;Sign=1;}/*初始化*/ 29 30 void Add_E(int x,int y,int z) 31 { 32 ID[Sign].to=y; 33 ID[Sign].v=z; 34 ID[Sign].next=First[x]; 35 First[x]=Sign++; 36 } 37 38 int Prim()/*Prim+堆维护*/ 39 { 40 priority_queue <Poin>Q; 41 Poin NUM; 42 int PP=P[1],i,NN=M,Sum=0,Vis[MAX]={0}; 43 for(i=1;i<=M;i++)Vis[P[i]]=1; 44 Vis[PP]=0;NN--; 45 for(i=First[PP];i;i=ID[i].next){Q.push(ID[i]);} 46 while(!Q.empty()&&NN) 47 { 48 NUM=Q.top();Q.pop(); 49 if(Vis[NUM.to]) 50 { 51 PP=NUM.to;Vis[PP]=0; 52 Sum+=NUM.v;NN--; 53 for(i=First[PP];i;i=ID[i].next) 54 Q.push(ID[i]); 55 } 56 } 57 if(!NN)return Sum; 58 else return -1; 59 } 60 61 62 void DFS(int d,int ii) 63 { 64 P[d]=ii; 65 if(d==M) 66 { 67 double E_Sum,P_Sum=0; 68 for(int i=1;i<=M;i++)P_Sum+=P_V[P[i]]; 69 E_Sum=Prim(); 70 Vlue=(double)E_Sum/((double)P_Sum); 71 if(Vlue-Min_V<-EXP) 72 { 73 for(int i=1;i<=M;i++)Min_P[i]=P[i]; 74 Min_V=Vlue; 75 } 76 // printf("\t%.5lf %.5lf %.5lf\n",E_Sum,P_Sum,Vlue); 77 return ; 78 } 79 for(int i=ii+1;i<=N;i++) 80 { 81 if(IDD[i]) 82 { 83 IDD[i]=0; 84 DFS(d+1,i); 85 IDD[i]=1; 86 } 87 } 88 return ; 89 } 90 91 int main() 92 { 93 int i,j,k,A,B,C; 94 while(scanf("%d%d",&N,&M)!=EOF) 95 { 96 if(N==0&&M==0)break; 97 Min_V=(double)INF;Sign=1; 98 for(i=1;i<=N;i++)scanf("%d",&P_V[i]); 99 for(i=1;i<=N;i++) 100 for(j=1;j<=N;j++) 101 scanf("%d",&Map[i][j]); 102 Cread(N); 103 for(i=1;i<=N;i++) 104 for(j=i+1;j<=N;j++) 105 {Add_E(i,j,Map[i][j]);Add_E(j,i,Map[i][j]);} 106 for(i=1;i<=N;i++)IDD[i]=1; 107 for(i=1;i<=N-M+1;i++) 108 { 109 IDD[i]=0; 110 DFS(1,i); 111 IDD[i]=1; 112 } 113 sort(Min_P+1,Min_P+M+1); 114 for(i=1;i<=M;i++) 115 { 116 if(i!=1)putchar(32); 117 printf("%d",Min_P[i]); 118 119 }putchar(10); 120 } 121 return 0; 122 }
转载请备注:
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************