题目:
2210 1020 2031 12 21000 1000 Sample Output1414.2oh! Author8600 Source2008浙大研究生复试热身赛(2)——全真模拟 Recommend思路:典型的kruskal算法和prime算法,直接看注释
代码1(Kruskal):
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <iostream>#include <stack>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define N 100+20#define M 10000+20#define MOD 1000000000+7#define inf 0x3f3f3f3fusing namespace std;int n,len;int pre[N],x[N],y[N];struct node{ int u,v; double w;} map[M];bool cmp(node a,node b){ return a.w<b.w;}void init(){ for(int i=1; i<=n; i++) pre[i]=i;}int find(int x){ if(x==pre[x]) return x; else { pre[x]=find(pre[x]); return pre[x]; }}int mix(int x,int y){ int fx=find(x); int fy=find(y); if(fx!=fy) { pre[fy]=fx; return 1; } return 0;}void Kruskal(){ sort(map,map+len,cmp); int cnt=0; double sum=0; for(int i=1; i<=len; i++) { if(map[i].w<10||map[i].w>1000) continue; if(mix(map[i].u,map[i].v))//判断是否已经连接 { cnt++; sum+=map[i].w*100; } if(cnt==n-1) break; } if(cnt<n-1) printf("oh!/n"); else printf("%.1lf/n",sum);}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d",&n); init(); double w; len=1; for(int i=1; i<=n; i++) { scanf("%d%d",&x[i],&y[i]); for(int j=1; j<i; j++)//枚举所有的岛 { w=sqrt((double)(x[i]-x[j])*(double)(x[i]-x[j])+(double)(y[i]-y[j])*(double)(y[i]-y[j])); map[len].u=i; map[len].v=j; map[len].w=w; len++; } } Kruskal(); } return 0;}代码2(Prime):#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <iostream>#include <stack>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define N 100+20#define M 10000+20#define MOD 1000000000+7#define inf 0x3f3f3f3fusing namespace std;int n,x[N],y[N];bool vis[N];double map[N][N],dis[N];void Prim(){ double minn; int k; for(int i=1; i<=n; i++) { dis[i]=map[1][i]; vis[i]=0; } vis[1]=1; double sum=0; for(int i=1; i<=n-1; i++)//一共要进行n-1次 { minn=inf; for(int j=1; j<=n; j++) { if(!vis[j]&&dis[j]<minn) { minn=dis[j]; k=j; } } if(minn==inf)//minn的值没有改变的话,那就是没有符合条件的 { printf("oh!/n"); return; } vis[k]=1; sum+=dis[k];//把选定的加上 for(int j=1; j<=n; j++) if(!vis[j]&&map[k][j]<dis[j]) dis[j]=map[k][j]; } printf("%.1lf/n",sum*100);}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d",&n); double w; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) i==j?map[i][j]=0:map[i][j]=inf; for(int i=1; i<=n; i++) { scanf("%d%d",&x[i],&y[i]); for(int j=1; j<i; j++)//计算多组数据的距离 { w=sqrt((double)(x[i]-x[j])*(double)(x[i]-x[j])+(double)(y[i]-y[j])*(double)(y[i]-y[j])); if(w>1000||w<10)//不满足条件的直接设为无穷大 map[i][j]=map[j][i]=inf; else map[i][j]=map[j][i]=w; } } Prim(); } return 0;}
新闻热点
疑难解答