hdu2489:http://acm.hdu.edu.cn/showproblem.php?pid=2489
题意:给你一个n个节点图,图的点有边权和点权,然后选取m个节点的子图,然后求这个一棵树,然后让这棵树的所有边权之和/所有点权之和的值最少。
题解:n很小,只有15,所以可以直接暴力,枚举每一种情况,然后求每一种情况的最小生成树,取最小的就可以了。但是这里的学到一个新的东西。就是判断a<b的时候,有可能a==b的时候由于浮点误差,也会被判成a<b,但是题目要的是字典序最小的,所以相等的时候是不能取的,所以要先考虑a和b是否相等,在不等的情况下在进行a<b的判断。
1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 #include<cmath> 6 using namespace std; 7 int fa[30],node[30],ans[30],val[30],g[30][30]; 8 int n,m; 9 double last; 10 void init(){ 11 for(int i=1;i<=15;i++) 12 fa[i]=i; 13 } 14 int Find(int x){ 15 int s; 16 for(s=x;s!=fa[s];s=fa[s]); 17 while(x!=s){ 18 int temp=fa[x]; 19 fa[x]=s; 20 x=temp; 21 } 22 return s; 23 } 24 struct Node{ 25 int x,y; 26 int w; 27 bool operator<(const Node a)const{ 28 return w<a.w; 29 } 30 }num[300]; 31 void solve(int *a){ 32 int top=0,cost=0; 33 for(int i=1;i<=n;i++) 34 if(a[i])cost+=val[i]; 35 36 for(int i=1;i<=n;i++) 37 for(int j=1;j<=n;j++) 38 if(a[i]&&a[j]&&g[i][j]){ 39 num[++top].x=i; 40 num[top].y=j; 41 num[top].w=g[i][j]; 42 } 43 sort(num+1,num+top+1); 44 int ct1=0,ct2=0; 45 init(); 46 for(int i=1;i<=top;i++){ 47 int tx=Find(num[i].x); 48 int ty=Find(num[i].y); 49 if(tx==ty)continue; 50 else{ 51 fa[tx]=ty; 52 ct1+=num[i].w; 53 ct2++; 54 if(ct2==m-1)break; 55 } 56 } 57 if(ct2==m-1){ 58 double temp=(double)ct1/(double)cost; 59 if(abs(temp-last)>0.00000001&&temp<last){ 60 last=temp; 61 memset(ans,0,sizeof(ans)); 62 for(int i=1;i<=n;i++) 63 if(a[i]) 64 ans[i]=i; 65 } 66 } 67 } 68 void DFS(int depth,int start){ 69 if(depth==m+1){ 70 solve(node); 71 return; 72 } 73 for(int i=start;i<=n;i++){ 74 node[i]=1; 75 DFS(depth+1,i+1); 76 node[i]=0; 77 } 78 } 79 int main(){ 80 while(~scanf("%d%d",&n,&m)&&n){ 81 memset(g,0,sizeof(g)); 82 memset(ans,0,sizeof(ans)); 83 memset(node,0,sizeof(node)); 84 for(int i=1;i<=n;i++) 85 scanf("%d",&val[i]); 86 for(int i=1;i<=n;i++) 87 for(int j=1;j<=n;j++) 88 scanf("%d",&g[i][j]); 89 last=100000000.0; 90 DFS(1,1); 91 int aa=0; 92 for(int i=1;i<=n;i++) 93 if(ans[i]){ 94 if(!aa)printf("%d",ans[i]); 95 else 96 printf(" %d",ans[i]); 97 aa=1; 98 } 99 puts(""); 100 } 101 }