hdu 1598(最小生成树变形)

解题思路:这道题我一开始的思路是动规,dp_max[i][j]表示i-j的最大边,dp_min[i][j]表示i-j的最小边,可是这样会有问题,有可能最大边与最小边不在同一条路径上,这样就很麻烦了。

正解:参考了网上的思路,这里其实是最小生成树的变形。由于是最大边与最小边的差最小,可以先把所有边按从小到大排好序,接着就是kruskal的思路了,我们把边从小到大以此加入进去,如果start和end之间有通路,那么就说明找到了一条满足要求的路径了。注意,这里由于最小边暂时是未知的,我们应该还要先去枚举最小边。这道题确实是挺难想的,如果第一次接触的话。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn = 205;
const int inf = 0x7ffffff;
struct Edge
{
	int u,v,c;
}edge[1005];
int n,m,fa[maxn];

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

void Union(int x,int y)
{
	int fx = find(x);
	int fy = find(y);
	if(fx != fy)
		fa[fy] = fx;
}

void init()
{
	for(int i = 1; i <= n; i++)
		fa[i] = i;
}

bool cmp(Edge a,Edge b)
{
	return a.c < b.c;
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(int i = 0; i < m; i++)
			scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
		sort(edge,edge+m,cmp);
		int q;
		scanf("%d",&q);
		while(q--)
		{
			int ans = inf,tmp;
			int start,end;
			scanf("%d%d",&start,&end);
			for(int i = 0; i < m; i++)
			{
				init();
				tmp = inf;
				for(int j = i; j < m; j++)
				{
					Union(edge[j].u,edge[j].v);
					if(find(start) == find(end))
					{
						tmp = edge[j].c - edge[i].c;
						break;	//注意要break,否则tmp值会越来越大
					}
				}
				ans = min(ans,tmp);
			}
			if(ans == inf) ans = -1;
			printf("%d\n",ans);
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值