Minimal Ratio Tree
dfs+prim
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include<cstdio>
#include <cstring>
#include <queue>
#include<bitset>
typedef long long ll;
using namespace std;
const double inf=2000001.0;
int m,n;
double mi,v,u;
double node[100],e[100][100];
int vis[100],vis2[100],vis3[100];
double d[100];
double prim()
{
fill(d,d+100,inf);
fill(vis2,vis2+100,0);
int flag;
for(int i=1;i<=n;i++)
{
if(vis[i]==1)
{
flag=i;
break;
}
}
d[flag]=0.0;
double ans=0,sv=0;
for(int i=1;i<=n;i++)
{
if(vis[i]==1)
{
sv+=node[i];
}
}
for(int i=1;i<=n;i++)
{
int u=-1;
double mi=inf;
for(int j=1;j<=n;j++)
{
if(vis[j]==1&&vis2[j]==0&&d[j]<mi)
{
u=j;
mi=d[j];
}
}
if(u==-1)
break;
vis2[u]=1;
ans+=d[u];
for(int v=1;v<=n;v++)
{
if(vis[v]==1&&vis2[v]==0&&e[u][v]<d[v])
d[v]=e[u][v];
}
}
//cout<<ans<<' '<<sv<<endl;
return ans/sv;
}
void dfs(int x,int num)
{
if(x>n+1)
return ;
if(num>m)
return ;
if(num==m)
{
//for(int i=1;i<=n;i++)
// cout<<vis[i]<<' ';
//cout<<endl;
double ans=prim();
//cout<<ans<<endl;
if(ans<mi)
{
mi=ans;
memcpy(vis3, vis2, sizeof(vis2));
}
return ;
}
vis[x]=1;
dfs(x+1,num+1);
vis[x]=0;
dfs(x+1,num);
}
int main()
{
while(scanf("%d%d",&n,&m)&&n&&m)
{
mi=inf;
fill(vis,vis+n+1,0);
for(int i=1;i<=n;i++)
scanf("%lf",&node[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lf",&e[i][j]);
dfs(1,0);
//cout<<mi<<endl;
int flag=0;
for(int i=1;i<=n;i++)
{
if(vis3[i]!=0&&flag==1)
cout<<' '<<i;
if(!flag&&vis3[i]!=0)
{
cout<<i;
flag=1;
}
}
cout<<endl;
}
return 0;
}
HDU5253(最小生成树)连接管道
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include<cstdio>
#include <cstring>
#include <queue>
#include<bitset>
typedef long long ll;
using namespace std;
const int inf=2*1e6;
int n,m;
int G[1001][1001],f[800000];
struct edge
{
int u,v,c;
}e[2000005];
bool cmp(edge a,edge b)
{
return a.c<b.c;
}
int find(int x)
{
if(x==f[x]) return x;
else return f[x]=find(f[x]);
}
int kru(int n,int m)
{
int ans,num;
ans=0,num=0;
for(int i=0;i<n;i++)
f[i]=i;
for(int i=0;i<m;i++)
{
int fa=find(e[i].u);
int fb=find(e[i].v);
if(fa!=fb)
{
f[fa]=fb;
ans+=e[i].c;
num++;
if(num==n-1)
break;
}
}
return ans;
}
int main()
{
int q;
scanf("%d",&q);
int flag=1;
while(q--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
scanf("%d",&G[i][j]);
}
int cnt=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
int t=i*m+j;
if(i!=n-1)
{
e[cnt].u=t;
e[cnt].v=t+m;
e[cnt].c=abs(G[i][j]-G[i+1][j]);
cnt++;
}
if(j!=m-1)
{
e[cnt].u=t;
e[cnt].v=t+1;
e[cnt].c=abs(G[i][j]-G[i][j+1]);
cnt++;
}
}
}
sort(e,e+cnt,cmp);
/*for(int i=0;i<cnt;i+=2)
cout<<e[i].u<<' '<<e[i].v<<' '<<e[i].c<<endl;
cout<<endl;*/
int ans=kru(n*m,cnt);
printf("Case #%d:\n",flag);
flag++;
printf("%d\n",ans);
}
return 0;
}
HDU 4463 Outlets (确定一条边的裸树)
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include<cstdio>
#include <cstring>
#include <queue>
#include<bitset>
typedef long long ll;
using namespace std;
const int inf=2*1e6;
int n,m;
int G[1001][1001],f[800000],vis[5555],t;
int p,q;
struct node
{
int x,y;
}no[100];
struct edge
{
int u,v;
double c;
}e[20005];
bool cmp(edge a,edge b)
{
return a.c<b.c;
}
int find(int x)
{
if(x==f[x]) return x;
else return f[x]=find(f[x]);
}
double kru(int n,int m)
{
int num;
double ans=0;
num=0;
for(int i=0;i<n;i++)
f[i]=i;
for(int i=0;i<m;i++)
{
int fa=find(e[i].u);
int fb=find(e[i].v);
if(fa!=fb)
{
f[fa]=fb;
//cout<<e[i].c<<endl;
ans+=e[i].c;
num++;
if(num==n-1)
break;
}
}
return ans;
}
double dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
while(scanf("%d",&n)&&n)
{
cin>>p>>q;
p--,q--;
for(int i=0;i<n;i++)
cin>>no[i].x>>no[i].y;
e[0].u=p;
e[0].v=q;
e[0].c=dis(no[p],no[q]);
int cnt=1;
for(int i=0;i<n-1;i++)
{
for(int j=i;j<n;j++)
{
if(i==q&&j==p)
continue;
if(i==p&&j==q)
continue;
e[cnt].u=i;
e[cnt].v=j;
e[cnt].c=dis(no[i],no[j]);
cnt++;
}
}
sort(e+1,e+cnt+1,cmp);
double ans=kru(n,cnt+1);
printf("%.2lf\n",ans);
}
return 0;
}