hdu 2489 MST+dfs

http://acm.hdu.edu.cn/showproblem.php?pid=2489

题目大意是有n个顶点的无向完全图,要你选m个点,使得m个点构成的图的m-1条边的权重之和比上m个点的值的和最小,即Sum(edge weight)/Sum(point weight)最小;

由于题目的数据很小,因此我就直接暴力了。。。

就是从n个点中先选m个点,对应一个最小值,然后对这m个点进行搜索就可以了。。。

如果一开始就从第一个点就开始dfs,那么就可以保证最后的结果就是题目要求的。。。

View Code
 1 #include<iostream>

 2 const int N=20;

 3 const int inf=10000000;

 4 using namespace std;

 5 

 6 int node[N];//点的权值

 7 int recode[N];//保存点

 8 int edge[N][N];

 9 int lowcost[N];

10 int map[N][N];//用来保存边

11 int path[N]; //保存路径

12 int n,m;

13 double MIN;

14 

15 double  prim(int v0){

16     double sum=0;

17     for(int i=1;i<=m;i++){

18         lowcost[i]=map[v0][i];

19     }

20     lowcost[v0]=-1;

21     for(int i=1;i<m;i++){

22         int min=inf,v=-1;

23         for(int j=1;j<=m;j++){

24             if(lowcost[j]!=-1&&lowcost[j]<min){

25                 v=j,min=lowcost[j];

26             }

27         }

28         if(v!=-1){

29             sum+=lowcost[v];

30             lowcost[v]=-1;

31             for(int k=1;k<=m;k++){

32                 if(lowcost[k]!=-1&&map[v][k]<lowcost[k]){

33                     lowcost[k]=map[v][k];

34                 }

35             }

36         }

37     }

38     return sum;

39 }

40 void dfs(int v0,int count){

41     recode[count]=v0;

42     if(count==m){

43         for(int i=1;i<=m;i++){

44             map[i][i]=0;

45             for(int j=i+1;j<=m;j++){

46                 map[i][j]=map[j][i]=inf;

47             }

48         }

49         for(int i=1;i<=m;i++){

50             for(int j=1;j<=m;j++){

51                 map[i][j]=edge[recode[i]][recode[j]];

52             }

53         }

54         double s1=prim(1),s2=0;

55         for(int i=1;i<=m;i++){

56             s2+=node[recode[i]];

57         }

58         double s=s1/s2;

59         if(s<MIN){

60             MIN=s;

61             //保存路径

62             for(int i=1;i<=m;i++)

63                 path[i]=recode[i];

64         }

65     }

66     for(int i=v0+1;i<=n;i++)

67         dfs(i,count+1);

68 }

69 

70 int main(){

71     while(scanf("%d%d",&n,&m)!=EOF){

72         if(n==0&&m==0)break;

73         for(int i=1;i<=n;i++){

74             scanf("%d",&node[i]);

75         }

76         for(int i=1;i<=n;i++){

77             for(int j=1;j<=n;j++){

78                 scanf("%d",&edge[i][j]);

79             }

80         }

81         MIN=1e18;

82         for(int i=1;i<=n;i++)

83             dfs(i,1);

84         printf("%d",path[1]);

85         for(int i=2;i<=m;i++){

86             printf(" %d",path[i]);

87         }

88         printf("\n");

89     }

90     return 0;

91 }

 

你可能感兴趣的:(HDU)