【bzoj1050】 HAOI2006旅行comf 最小生成树

不错的题,lyp去年培训讲过,首先排一遍序,然后从小到大枚举每一条边,以这条边为最小边向后枚举,直到s和t联通,没了。。。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 10010

using namespace std;

struct yts
{
	int x,y,w;
}e[maxn];

int n,m,s,t,ans1,ans2;
int f[maxn];

bool cmp(yts x,yts y)
{
	return x.w<y.w;
}

int find(int x)
{
	if (f[x]==x) return x;
	else return f[x]=find(f[x]);
}

int gcd(int a,int b)
{
	if (b==0) return a;
	else return gcd(b,a%b);
}

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
	scanf("%d%d",&s,&t);
	sort(e+1,e+m+1,cmp);
	ans1=60000;ans2=1;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=n;j++) f[j]=j;
		int j;
		bool w=0;
		for (j=i;j<=m;j++)
		{
			int f1=find(e[j].x),f2=find(e[j].y);
			if (f1!=f2) f[f1]=f2;
			if (find(s)==find(t)) {w=1;break;} 
		}
		if (w && e[j].w*ans2<ans1*e[i].w) ans1=e[j].w,ans2=e[i].w;
	}
	int GCD=gcd(ans1,ans2);
	ans1/=GCD;ans2/=GCD;
	if (ans1==60000) printf("IMPOSSIBLE\n");
	else if (ans2==1) printf("%d\n",ans1);
	else printf("%d/%d\n",ans1,ans2);
	return 0;
}


你可能感兴趣的:(【bzoj1050】 HAOI2006旅行comf 最小生成树)