从零单排17

呵呵呵呵

prim和dijsktra太像了。。。

然后终于会写kruskal了。。。

今天收获好多感觉。。。

状态特别好。。。


hdu 1879:http://acm.hdu.edu.cn/showproblem.php?pid=1879

/*
手打最小生成树。。
prim和dijsktra太像了。。
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[105][105];
int dis[105];
int visit[105];
int n,N;
void getmap()
{
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			map[i][j]=map[j][i]=i==j?0:INF;
		}
	}
	while(N--)
	{
		int s,e,l,flag;
		cin>>s>>e>>l>>flag;
		if(flag)
		{
			map[s][e]=map[e][s]=0;
		}
		else
		{
			map[s][e]=map[e][s]=l;
		}
	}
}
void prim()
{
	int k=1;
	int ans=0;
	memset(visit,0,sizeof(visit));
	memset(dis,INF,sizeof(dis));
	for(int i=1;i<=n;i++)
	{
		dis[i]=map[1][i];
	}
	visit[1]=1;
	for(int i=1;i<n;i++)
	{
		int MIN=INF;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j]&&dis[j]<MIN)
			{
				MIN=dis[j];
				k=j;
			}
		}
		if(MIN==INF)
			break;
		visit[k]=1;
		ans+=MIN;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j])
			{
				dis[j]=min(dis[j],map[k][j]);
			}
		}
	}
	cout<<ans<<endl;
}
int main()
{
	while(cin>>n&&n!=0)
	{
		N=n*(n-1)/2;
		getmap();
		prim();
	}
	system("pause");
	return 0;
}

hdu 1233: http://acm.hdu.edu.cn/showproblem.php?pid=1233

/*
真的是灰常轻松的模版题
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int map[105][105];
int visit[105];
int dis[105];
int n,N;
void getmap()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			map[i][j]=map[j][i]=i==j?0:INF;
		}
	}
	while(N--)
	{
		int s,e,l;
		scanf("%d%d%d",&s,&e,&l);
		map[s][e]=map[e][s]=min(map[s][e],l);
	}
}
void prim()
{
	int k=1;
	int ans=0;
	memset(visit,0,sizeof(visit));
	memset(dis,INF,sizeof(dis));
	for(int i=1;i<=n;i++)
	{
		dis[i]=map[1][i];
	}
	visit[1]=1;
	for(int i=1;i<n;i++)
	{
		int MIN=INF;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j]&&dis[j]<MIN)
			{
				MIN=dis[j];
				k=j;
			}
		}
		if(MIN==INF)
			break;
		visit[k]=1;
		ans+=MIN;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j])
			{
				dis[j]=min(dis[j],map[k][j]);
			}
		}
	}
	cout<<ans<<endl;
}
int main()
{
	while(scanf("%d",&n)!=EOF&&n!=0)
	{
		N=n*(n-1)/2;
		getmap();
		prim();
	}
	system("pause");
	return 0;
}

hdu 1875:http://acm.hdu.edu.cn/showproblem.php?pid=1875

/*
处理一下输入就好,
将不符合位于10-1000区间的点视为不连通就好
*/
#include<iostream>
#include<algorithm>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
double map[105][105];
double dis[105];
int visit[105];
int n;
struct point
{
	double x;
	double y;
}a[105];
double dist(int i,int j)
{
	return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
void getmap()
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			map[i][j]=i==j?0:INF;
		}
	}
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].x>>a[i].y;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			double len=dist(i,j);
			if(len>=10&&len<=1000)
			{
				map[i][j]=map[j][i]=len*100;
			}
		}
	}
}
void prim()
{
	int k;
	double ans=0;
	memset(visit,0,sizeof(visit));
	memset(dis,INF,sizeof(dis));
	for(int i=1;i<=n;i++)
	{
		dis[i]=map[1][i];
	}
	visit[1]=1;
	int i;
	for(i=1;i<n;i++)
	{
		double MIN=INF;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j]&&dis[j]<MIN)
			{
				MIN=dis[j];
				k=j;
			}
		}
		if(MIN==INF)
			break;
		visit[k]=1;
		ans+=MIN;
		for(int j=1;j<=n;j++)
		{
			if(!visit[j])
			{
				dis[j]=min(dis[j],map[k][j]);
			}
		}
	}
	if(i!=n)
	{
		cout<<"oh!"<<endl;
	}
	else
	{
		printf("%.1lf\n",ans);
	}
}		
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n;
		getmap();
		prim();
	}
	system("pause");
	return 0;
}

hdu 1232: http://acm.hdu.edu.cn/showproblem.php?pid=1232 额。。并查集乱入

/*
并查集裸题~
1A
*/
#include<iostream>
using namespace std;
int father[1005];
int n;
void init()
{
	for(int i=1;i<=n;i++)
	{
		father[i]=i;
	}
}
int find(int x)
{
	if(x==father[x])
	{
		return x;
	}
	else
	{
		return find(father[x]);
	}
}
void Union(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		father[x]=y;
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF&&n!=0)
	{
		int m;
		scanf("%d",&m);
		init();
		while(m--)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			Union(x,y);
		}
		int ans=1;
		for(int i=1;i<=n;i++)
		{
			if(father[i]==i)
			{
				ans++;
			}
		}
		printf("%d\n",ans-2);
	}
	system("pause");
	return 0;
}
			

hdu 1233: http://acm.hdu.edu.cn/showproblem.php?pid=1233  kruskal算法哈哈

/*
终于会写kruskal了哈哈
*/
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int father[5000];
struct road
{
	int x;
	int y;
	int len;
}r[5000];
bool cmp(const road &a,const road &b)
{
	return a.len<b.len;
}
int find(int x)
{
	if(x==father[x])
	{
		return x;
	}
	else
	{
		return find(father[x]);
	}
}
int ans;
int n;
int N;
void Union(road temp)
{
	int x=find(temp.x);
	int y=find(temp.y);
	if(x!=y)
	{
		ans+=temp.len;
		father[x]=y;
	}
}
void getmap()
{
	for(int i=1;i<=N;i++)
	{
		scanf("%d%d%d",&r[i].x,&r[i].y,&r[i].len);
	}
}
void kruskal()
{
	for(int i=1;i<=N;i++)
	{
		father[i]=i;
	}
	sort(r+1,r+N+1,cmp);
	for(int i=1;i<=N;i++)
	{
		Union(r[i]);
	}
	printf("%d\n",ans);
}
	
int main()
{
	while(scanf("%d",&n)!=EOF&&n!=0)
	{
		N=n*(n-1)/2;
		getmap();
		ans=0;
		kruskal();
	}
	system("pause");
	return 0;
}


感觉纠结好久的东西突然一下子解决了~~~

今晚搞搞别的东西吧~

写的有点累了~~

加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值