传送Door
题解
这题题面好像挺复杂,其实就是个果的Prim算法。yy一下就知道第二条规则纯属吹B,没有卵用。一个最小生成树题目,为什么一定要用Prim呢?因为题目处处提醒你这题就是要用Prim。因为这题是完全图,边很多,开不下。因为 O(n2) 的Prim能够出色胜任,连数据结构优化都不用。
由于我好像没有写过几次Prim,就当复习一下,为NOIP打基础。好像挺容易的(按照题目说的去做就行了=。=)。
程序
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#define maxn 5005
#define oo 0x7fffffff
using namespace std;
int n;
int x[maxn], y[maxn];
double d[maxn], ans;
bool vis[maxn];
double Calc(int u, int v){
double dx = (double)(x[u] - x[v]);
double dy = (double)(y[u] - y[v]);
return sqrt(dx * dx + dy * dy);
}
int main(){
freopen("lgP1265.in", "r", stdin);
freopen("lgP1265.out", "w", stdout);
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d%d", &x[i], &y[i]);
for(int i = 1; i <= n; i++)
d[i] = Calc(1, i);
vis[1] = true;
for(int i = 1; i < n; i++){
double _min = oo;
int p;
for(int j = 1; j <= n; j++){
if(vis[j]) continue;
if(d[j] < _min){
_min = d[j];
p = j;
}
}
ans += _min;
vis[p] = true;
for(int j = 1; j <= n; j++)
d[j] = min(d[j], Calc(p, j));
}
printf("%.2lf\n", ans);
return 0;
}
永远不会开始的两人
是否可以一直走下去
永远不会开场的故事
是否也铭刻下了轨迹
——《平行线》