【H - Highways】

最小生成树算法对比
本文对比了Kruskal和Prim两种最小生成树算法在解决特定问题时的表现。指出Kruskal算法因递归和内存限制易导致失败,而Prim算法则更为稳定高效。通过具体代码实现,展示了不同算法在实际应用中的优劣。

思路:

  • 最小生成树
  • 使用 Kruskal 不停 MLE,改成 Prim 才过掉。
  • Kruskal:不能写递归的FIND,会爆栈MLE;几处小优化都要加,很容易TLE。
  • Prim:随便写写就过了。
  • 另有不解之处,见代码。

代码:

  • Kruskal:625ms 3948kB
//625ms		3948kB


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;

const int maxn = 755;

int N,M;
int num;
int par[maxn];
struct NODE{
	int x;
	int y;
}node[maxn];
struct EDGE{
	int u , v , w;
	friend bool operator < (EDGE a , EDGE b){
		return a.w < b.w; 
	}
}edge[maxn * maxn / 2];int cnt;
void ADDEDGE(int u,int v,int w){
	edge[cnt].u = u;
	edge[cnt].v = v;
	edge[cnt].w = w;
	cnt++;
}

void INIT(){
	cnt = 0;
	num = 0;
	memset(par , -1 , sizeof(par));
	return ;
}

int FIND(int i){
	while(par[i] != -1)
		i = par[i];
	return i;
}//递归会爆栈,MLE 

void UNION(int l,int r){
	int parl = FIND(l);
	int parr = FIND(r);
	if(parl == parr)
		return ; //优化
	par[parl] = parr;
	return ;
}

void KRUSKAL(){
	sort(edge , edge + cnt);
	for(int i=0;i<cnt;i++){
		if(num == N-1)
			break;//优化
		int u = edge[i].u;
		int v = edge[i].v;
		int w = edge[i].w;
		int parl = FIND(u);
		int parr = FIND(v);
		if(parl != parr){
			UNION(u,v);
			num++;
			printf("%d %d\n" , u , v);
		}
	}
	return ;
}

int main(){
	INIT();
	scanf("%d" , &N);
	for(int i=1;i<=N;i++)
		scanf("%d%d" , &node[i].x , &node[i].y);
	scanf("%d" , &M);
	for(int i=1;i<=M;i++){
		int u,v;
		scanf("%d%d" , &u , &v);
		UNION(u,v);
	}
	for(int i=1;i<=N;i++)
		for(int j=i+1;j<=N;j++){
			if(FIND(i) == FIND(j))
				continue;
			int w = (node[i].x - node[j].x)*(node[i].x - node[j].x) + (node[i].y - node[j].y)*(node[i].y - node[j].y);
			ADDEDGE(i,j,w);
		}
	KRUSKAL();
	return 0;
}
  • Prim:204ms 3528kB
//204ms		3528kB


#include <iostream>
#include <cstring>
#include <queue>
#define INF 0x3f3f3f3f

using namespace std;

const int maxn = 755;

int N,M;
int mp[maxn][maxn];
int dis[maxn];
bool vis[maxn];
struct ORD{
	int x;
	int y;
}ord[maxn];//coordinate
struct NODE{
	int id;
	int par;
	int dis;
	friend bool operator > (NODE a , NODE b)
	{
		return a.dis > b.dis ;
	}
	NODE(int id,int par,int dis) : id(id) , par(par) , dis(dis) {} ;
};
priority_queue <NODE , vector<NODE> , greater<NODE> > Q;

void INIT(){
	memset(vis , 0 , sizeof(vis));
	memset(dis , INF , sizeof(dis));
	memset(mp , 0 , sizeof(mp));
	return ;
}

void PRIM(){
	dis[1] = 0;
	Q.push(NODE(1 ,-1, 0)) ; 
	while(Q.size()){
		NODE cur = Q.top() ; Q.pop() ;
		int id = cur.id;
		if(vis[id])
			continue;
		vis[id] = true;
		if(dis[id]){
			//如果改成:if(par[id] != -1 && dis[id])速度竟然会提高很多。不解。
			cout<<cur.par<<' '<<id<<endl;
		}
		for(int i=1;i<=N;i++)
			if(!vis[i] && dis[i] > mp[id][i]){
				dis[i] = mp[id][i];
				Q.push(NODE(i , id , dis[i]));
			}
	}
	return ;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	INIT();
	cin>>N;
	for(int i=1;i<=N;i++)
		cin>>ord[i].x>>ord[i].y;
	for(int i=1;i<=N;i++)
		for(int j=i+1;j<=N;j++)
			mp[i][j] = mp[j][i] = (ord[i].x-ord[j].x)*(ord[i].x-ord[j].x) + (ord[i].y-ord[j].y)*(ord[i].y-ord[j].y);
	cin>>M;
	for(int i=1;i<=M;i++){
		int l,r;
		cin>>l>>r;
		mp[l][r] = mp[r][l] = 0;
	}
	PRIM();
	return 0;
}
用r语言解决以下问题:Boston Housing Data. The Boston housing data set was collected by Harrison and Rubinfeld (1978). It comprise 506 observations for each census district of the Boston metropolitan area. The data set was analyzed in Belsley et al. (1980). • X1: per capita crime rate, • X2: proportion of residential land zoned for large lots, • X3: proportion of nonretail business acres, • X4: Charles River (1 if tract bounds river, 0 otherwise), • X5: nitric oxides concentration, • X6: average number of rooms per dwelling, • X7: proportion of owner-occupied units built prior to 1940, • X8: weighted distances to five Boston employment centers, • X9: index of accessibility to radial highways, • X10: full-value property tax rate per $10,000, • X11: pupil/teacher ratio, • X12: 1000(B−0.63)2 I(B < 0.63) where B is the proportion of African American, • X13: % lower status of the population, • X14: median value of owner-occupied homes in $1000. Car Data. The car data set Chambers et al. (1983) consists of 13 variables measured for 74 car types. The abbreviations in this section are as follows: • X1:P Price, • X2:M Mileage (in miles per gallone), • X3:R78 Repair record 1978 (5–point scale; 5 best, 1 worst), • X4:R77 Repair record 1977 (scale as before), • X5:H Headroom (in inches), • X6:R Rear seat clearance (distance from front seat back to rear seat, in inches), • X7:Tr Trunk space (in cubic feet), • X8:W Weight (in pound), 2 • X9:L Length (in inches), • X10:T Turning diameter (required to make a U-turn, in feet), • X11:D Displacement (in cubic inches), • X12:G Gear ratio for high gear, • X13:C Company headquarter (1 - U.S., 2 - Japan, 3 - Europe). Banknote Data. Six variables measured on 100 genuine and 100 counterfeit old Swiss 1000- franc bank notes. The data stem from Flury and Riedwyl (1988). The columns correspond to the following 6 variables: • X1: Length of the bank note, • X2: Height of the bank note, measured on the left, • X3: Height of the bank note, measured on the right, • X4: Distance of inner frame to the lower border, • X5: Distance of inner frame to the upper border, • X6: Length of the diagonal. Observations 1–100 are the genuine bank notes and the other 100 observations are the counterfeit bank notes. Job Applicants Data In this study, 48 individuals who had applied for a job with a large firm were interviewed and rated on 15 criteria. Individuals were rated on the form of their letter of application (FL), their appearance (APP), academic ability (AA), likability (LA), selfconfidence (SC), lucidity (LC), honesty(HON), salesmanship (SMS), experience (EXP), drive (DRV), ambition (AMB), ability to grasp concepts (GSP), potential (POT), keenness to join (KJ), and their suitability (SUIT). Each criterion was evaluated on a scale ranging from 0 to 10, with 0 being a very low and very unsatisfactory rating, and 10 being a very high rating.
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值