#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define nn 1100
#define inf 9999999
using namespace std;
int n,m;
int g[20][20];
int a[20];
int fa[20];
int node[20];
struct eg
{
int u,v,w;
}edge[500];
double ans;
int res[20];
int find(int x)
{
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
bool cmp(const eg&a,const eg&b)
{
return a.w<b.w;
}
void mst()
{
int i,j,k=0;
int nsum=0,esum=0;
for(i=1;i<=n;i++)
fa[i]=i;
for(i=1;i<=n;i++)
{
if(node[i]==1)
{
nsum+=a[i];
for(j=i+1;j<=n;j++)
if(node[j]==1)
{
edge[k].u=i;
edge[k].v=j;
edge[k++].w=g[i][j];
}
}
}
sort(edge,edge+k,cmp);
int cnt=0;
for(i=0;i<k;i++)
{
int fu=find(edge[i].u);
int fv=find(edge[i].v);
if(fu!=fv)
{
fa[fu]=fv;
esum+=edge[i].w;
cnt++;
}
if(cnt==m-1)
break;
}
// printf("%d %d\n",esum,nsum);
double tmp=(double)esum/(double)nsum;
if(tmp-ans<-(1e-9))
{
ans=tmp;
for(i=1;i<=n;i++)
res[i]=node[i];
}
}
void dfs(int id,int num)
{
if(num==m)
{
mst();
return ;
}
if(id==n+1)
return;
node[id]=1;
dfs(id+1,num+1);
node[id]=0;
dfs(id+1,num);
}
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==2&&(n||m))
{
int i,j;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&g[i][j]);
memset(node,0,sizeof(node));
ans=1e18;
dfs(1,0);
int flag=0;
for(i=1;i<=n;i++)
{
if(res[i]==0) continue;
if(flag==1)
printf(" ");
flag=1;
printf("%d",i);
}
printf("\n");
}
return 0;
}
从N个中选M个,DFS枚举,不会写,让猪教的
void dfs(int id,int num)
{
if(num==m)
{
mst();
return ;
}
if(id==n+1)
return;
node[id]=1;
dfs(id+1,num+1);
node[id]=0;
dfs(id+1,num);
}
对当前这个点 有两种操作 选还是不选 第一个dfs是就是选 位置往后移一个 sum+1
这个问题解决了,就好办了
尼玛,调试了半天,求成最大生成树了,脑残啊,精度卡得我也很无语