省选专练[HAOI2006]旅行

本文介绍了一个06年的省级选拔赛中的生成树算法题解,通过排序边权并枚举最小值和最大值的方法求解,提供了一段完整的C++代码实现。

06年的天是晴朗的

一年省选两天生成树签到。

n*m可以过。

先排序,使边权单调。

然后再枚举最小值和最大值。

比较一下就好了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#define N 20000
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
	x=0;
	int f=1;
	char ch=nc();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=nc();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=nc();
	}
	x*=f;
}
struct Front_star{
	int u,v,w;
}e[N*4];
int cnt=0;
void add(int u,int v,int w){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].w=w;
}
bool cmp(Front_star a,Front_star b){
	return a.w<b.w;
}
int fa[N]={0};
int n,m;
int s,t;
int getfa(int x){
	if(fa[x]==x){
		return x;
	}
	else{
		return fa[x]=getfa(fa[x]);
	}
}
void uni(int x,int y){
	int dx=getfa(x);
	int dy=getfa(y);
	fa[dx]=dy;
}
int gcd(int x,int y){
	while(y){
		int temp=y;
		y=x%y;
		x=temp;
	}
	return x;
}
int main(){
	read(n);
	read(m);
	for(int i=1;i<=m;i++){
		int u,v,w;
		read(u);
		read(v);
		read(w);
		add(u,v,w);
	}
	read(s);
	read(t);
	sort(e+1,e+1+cnt,cmp);
	int ans1=0,ans2=0;
	e[0].w=0;
	for(int i=1;i<=m;++i){
		for(int j=1;j<=n;++j){
			fa[j]=j;
		}
		fa[0]=2000;
		int idx=20000;
		e[idx].w=50000;
//		cout<<i<<endl;
		for(int j=i;j<=m;++j){
			uni(e[j].u,e[j].v);
//			cout<<j<<endl;
			if(getfa(s)==getfa(t)){
				idx=j;
				break;
			}
		}
		
		if(i==1&&getfa(s)!=getfa(t)){
			cout<<"IMPOSSIBLE";
			return 0;
		}
		
		if(e[ans2].w*e[i].w>=e[ans1].w*e[idx].w){
			ans1=i;
			ans2=idx;
//			cout<<ans1<<" "<<ans2<<endl;
		}
		
	}
//	cout<<ans1<<"---"<<ans2;
	int G=(gcd(e[ans1].w,e[ans2].w));
	ans1=e[ans1].w/G;
	ans2=e[ans2].w/G;
	if(ans1==1){
		cout<<ans2;
	}
	else{
		cout<<ans2<<"/"<<ans1;
	}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值