1. 程式人生 > >CDOJ 1146 秋實大哥與連鎖快餐店

CDOJ 1146 秋實大哥與連鎖快餐店

cst 快餐 algo 一次 double point esp clas div

第一次做prim的最小生成樹的題目,據說相比kruskal更適應稠密圖,用kruskal會mle?(待測)

關於題目:所有的旗艦店相當於已經連通,其他點沒有連通,然而有一個小問題:n個點中有k個旗艦店,應該連n-k條路,但是循環結束標誌為i=n-k-1確實wa7,只有將循環結束標誌設置為所有的lowcost都為0時才可以,一直沒想通兩者的區別?

#include<cstdio>
#include<algorithm>
#include<math.h>
#define maxn 6666+50
#define inf 1e12
using namespace std;
typedef 
struct Point { double x; double y; int type; }; int n; Point poi[maxn]; double lowcost[maxn]; int liansuo=0; double dist(int i,int j) { double disx=fabs(poi[i].x-poi[j].x); double disy=fabs(poi[i].y-poi[j].y); return sqrt(disx*disx+disy*disy); } double prim(void) { int i,j;
double res=0; for(i=1;i<=n;i++) { lowcost[i]=inf; } for(i=1;i<=n;i++) { if(poi[i].type==1) { lowcost[i]=0; } else if(poi[i].type==0) { for(j=1;j<=n;j++) { if(poi[j].type==1) {
double temp=dist(i,j); if(temp<lowcost[i]) { lowcost[i]=temp; } } } } } for(i=1;i<=n;i++) { double tt=inf; int ttind=-1; for(j=1;j<=n;j++) { if(lowcost[j]!=0) { if(lowcost[j]<tt) { tt=lowcost[j]; ttind=j; } } } if(ttind==-1) { return res; } res=res+tt; lowcost[ttind]=0; for(j=1;j<=n;j++) { if(lowcost[j]!=0) { double tempdis=dist(j,ttind); lowcost[j]=min(tempdis,lowcost[j]); } } } return res; } int main() { int i,j; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%lf%lf%d",&poi[i].x,&poi[i].y,&poi[i].type); if(poi[i].type==1) { liansuo++; } } double ans=prim(); printf("%.2lf\n",ans); return 0; }

CDOJ 1146 秋實大哥與連鎖快餐店