JZOJ 3514. 最小比例
题目
分析
- n这么小显然暴力
- 因为每次我们选的点是一定的
- 所以我们要求最小边,最小生成树即可
代码
1 #include<iostream> 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 int map[30][30]; 7 int t[30],b[30],flag[30],ans[30],dis[30],vis[30],fz1,fz2,fm1,fm2; 8 double last=10000000000.0000; 9 int n,m; 10 void check(int sum) 11 { 12 int cnt=0,anss=1e9; 13 int a=b[1]; 14 memset(dis,0x3f,sizeof(dis)); 15 memset(vis,0,sizeof(vis)); 16 dis[a]=0; 17 vis[a]=1; 18 for (int j=2;j<=m;j++) 19 dis[b[j]]=min(dis[b[j]],map[a][b[j]]); 20 int ss=0; 21 cnt=0; 22 while (++cnt<=m-1) 23 { 24 int wz=0,minn=1e9; 25 for (int j=1;j<=m;j++) 26 { 27 int y=b[j]; 28 if (!vis[y]&&dis[y]<minn) 29 { 30 minn=dis[y]; 31 wz=y; 32 } 33 } 34 vis[wz]=1; 35 for (int j=1;j<=m;j++) 36 { 37 int y=b[j]; 38 if (!vis[y]) 39 dis[y]=min(dis[y],map[wz][y]); 40 } 41 ss+=minn; 42 } 43 anss=min(anss,ss); 44 double k=(double)anss/(double)sum; 45 if (k<last) 46 { 47 last=k; 48 for (int i=1;i<=m;i++) 49 ans[i]=b[i]; 50 } 51 } 52 void dfs(int f,int sum) 53 { 54 if (f>m) 55 { 56 check(sum); 57 return; 58 } 59 for (int i=b[f-1]+1;i<=n;i++) 60 { 61 if (!flag[i]) 62 { 63 flag[i]=1; 64 b[f]=i; 65 dfs(f+1,sum+t[i]); 66 flag[i]=0; 67 } 68 } 69 } 70 int main () 71 { 72 freopen("ratio.in","r",stdin); 73 freopen("ratio.out","w",stdout); 74 cin>>n>>m; 75 for (int i=1;i<=n;i++) 76 cin>>t[i]; 77 for (int i=1;i<=n;i++) 78 for (int j=1;j<=n;j++) 79 cin>>map[i][j]; 80 dfs(1,0); 81 for (int i=1;i<=m;i++) cout<<ans[i]<<" "; 82 }
为何要逼自己长大,去闯不该闯的荒唐