1344 线型网络

1344 线型网络

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
题目描述 Description

有 N ( <=20 ) 台 PC 放在机房内,现在要求由你选定一台 PC,用共 N-1 条网线从这台机器开始一台接一台地依次连接他们,最后接到哪个以及连接的顺序也是由你选定的,为了节省材料,网线都拉直。求最少需要一次性购买多长的网线。(说白了,就是找出 N 的一个排列 P1 P2 P3 ..PN 然后 P1 -> P2 -> P3 -> ... -> PN 找出 |P1P2|+|P2P3|+...+|PN-1PN| 长度的最小值)

输入描述 Input Description

第一行 N ,下面 N 行,每行分别为机器的坐标(x,y) ( 实数 -100<=x,y<=100 )

输出描述 Output Description

最小的长度,保留两位小数。

样例输入 Sample Input

3
0 0
1 1
1 -1

样例输出 Sample Output

2.83

数据范围及提示 Data Size & Hint
 
 
一上来,没思考,mst,样例过来,然后就过了一个点

#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define b(i) i*i #define N 31 struct node{ int x,y; }a[N]; struct ss{ int x,y; double val; bool operator < (const ss &t)const{return val<t.val;} }e[N*N]; int n,cnt,fa[N]; inline double run(node p,node q){ return sqrt(b(p.x-q.x)+b(p.y-q.y)); } int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) continue; e[++cnt].x=i;e[cnt].y=j; int tmp=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y); e[cnt].val=sqrt(tmp); } } //for(int i=1;i<=cnt;i++) printf("%d %d %.2lf\n",e[i].x,e[i].y,e[i].val); sort(e+1,e+cnt+1); int k=0;double ans=0; for(int i=1;i<=cnt;i++){ int fx=find(e[i].x),fy=find(e[i].y); if(fx!=fy){ fa[fx]=fy; ans+=e[i].val; if(++k==n-1) break; } } printf("%.2lf\n",ans); return 0; }

附上第一个WA点

看了题解:

此人太懒,大量随机数验证。和费马斯小定理如出一辙。倒是也省了dfs

AC代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<iostream>
using namespace std;
#define N 21
int n,a[N];
double x[N],y[N],dis[N][N];
inline double run(double a,double b){
    return sqrt(a*a+b*b);
}
inline double len(int i,int j){
    return a[i]<a[j]?dis[a[i]][a[j]]:dis[a[j]][a[i]];
}
int main(){
    srand(time(0));
    ios::sync_with_stdio(0);
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>x[i]>>y[i];
        for(int j=0;j<i;j++){
            dis[j][i]=run(x[i]-x[j],y[i]-y[j]);
        }
    }
    double ans=0x7fffffff,tmp=0;
    for(int t=0;t<10000;t++){
        for(int i=0;i<n;i++) a[i]=i;
        for(int i=0;i<n;i++){
            int j=rand()%(n-i)+i;
            if(i==j) continue;
            swap(a[i],a[j]);
        }
        bool flag=1;
        for(;flag;){
            flag=0;
            for(int i=2;i<n-1;i++){
                for(int j=1;j<i;j++){
                    if(len(j-1,j)+len(i,i+1)>len(j-1,i)+len(j,i+1)){
                        while(i>j){
                            swap(a[i],a[j]);
                            i--;j++;
                        }
                        flag=1;
                        break;
                    }
                }
                if(flag) break;
            }
        }
        tmp=0;
        for(int i=1;i<n;i++) tmp+=len(i,i-1);
        ans=min(ans,tmp);
    }
    cout.precision(2);
    cout.setf(ios::fixed);
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2016-08-09 16:56  神犇(shenben)  阅读(1960)  评论(0编辑  收藏  举报