1050: [HAOI2006]旅行comf

枚举大法好。

先对边进行排序,然后枚举最大边,初始化并查集,依次加入更小的边,第一次连通时,更新答案,一轮枚举结束。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=1e9;
struct Edge{
	int u,v,w;
	bool operator<(const Edge& rhs)const{
		return w>rhs.w;
	}
}e[5005];
int pa[505],n,m;
int findset(int x){
	return pa[x]!=x?findset(pa[x]):pa[x];
}
void init(){
	for(int i=1;i<=n;i++)pa[i]=i;
}
int gcd(int a,int b){
	return (!b)?a:gcd(b,a%b);
}
double divi(double a,double b){
	return a/b;
}
int main(){
	scanf("%d%d",&n,&m);
	int s,t;
	for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
	scanf("%d%d",&s,&t);
	sort(e+1,e+1+m);
	int up=inf,down=1;
	for(int i=1;i<=m;i++){
		int a=e[i].w,b;
		init();
		for(int j=i;j<=m;j++){
			b=e[j].w;
			int u=findset(e[j].u),v=findset(e[j].v);
			if(u!=v)pa[u]=v;
			if(findset(s)==findset(t)){
				if(divi(up,down)>divi(a,b)){
					up=a;
					down=b;
				}
				break;
			}
		}
	}
	int d=gcd(up,down);
	up/=d;down/=d;
	if(up>=inf)printf("IMPOSSIBLE");
	else if(down==1)printf("%d",up);
	else printf("%d/%d",up,down);
	return 0;
}


你可能感兴趣的:(1050: [HAOI2006]旅行comf)