想看更多的解题报告: http://iyenn.com/rec/1824570.html
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:有N个农场,现在给出他们的坐标,并且已经知道了有些农场他们之间是已经相连的了,现在问怎么连最小的边,能将这些农场都连接起来
解题思路:变相的最小生成树,即将已经连起来的边的权值置为-1,那么根据prim算法,优先选的就是那条-1边,这样我们在选边的时候,如果是-1边我们就可以不用加进来
- /*
- Memory 8096K
- Time 94MS
- */
- #include
- #include
- #define MAXV 1005
- #define inf 1e12
-
- typedef struct{
- double x,y;
- }Point;
-
- Point point[MAXV];
-
- int n,m;
- double map[MAXV][MAXV];
-
- double distance(Point a,Point b){
- return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
- }
-
- void prim(){
- int i,j,vis[MAXV],v;
- double mi,d[MAXV];
- for(i=1;i<=n;i++){
- vis[i]=0;
- d[i]=map[1][i];
- }
-
- for(i=1;i<=n;i++){
- mi=inf;
- for(j=1;j<=n;j++)
- if(!vis[j] && d[j]
- mi=d[j];
- v=j;
- }
- vis[v]=1;
-
- for(j=1;j<=n;j++)
- if(!vis[j] && d[j]>map[v][j])
- d[j]=map[v][j];
- }
-
- for(d[0]=0,i=1;i<=n;i++)
- if(d[i]!=-1) d[0]+=d[i];
- printf("%.2lf\n",d[0]);
- }
-
- int main(){
- int i,j,a,b;
- while(~scanf("%d%d",&n,&m)){
- for(i=1;i<=n;i++) scanf("%lf%lf",&point[i].x,&point[i].y);
- for(i=1;i<=n;i++)
- for(j=1;j<=n;j++)
- map[i][j]=map[j][i]=distance(point[i],point[j]);
- for(i=1;i<=m;i++){
- scanf("%d %d",&a,&b);
- map[a][b]=map[b][a]=-1;
- }
- prim();
- }
- return 0;
- }
评论记录:
回复评论: