首页 > 代码库 > 51nod 1640 天气晴朗的魔法 (最小生成树)
51nod 1640 天气晴朗的魔法 (最小生成树)
这样阴沉的天气持续下去,我们不免担心起他的健康。
两个正整数N,M。(1 <= N <= 10^5, N <= M <= 2 * 10^5)接下来M行,每一行有三个整数A, B, V。(1 <= A, B <= N, INT_MIN <= V <= INT_MAX)保证输入数据合法。
输出一个正整数R,表示符合条件的魔法阵的魔力值之和。
4 61 2 31 3 11 4 72 3 42 4 53 4 6
12
分析:要求阵中的魔法链的魔力值最大值尽可能的小,那么最小会小到什么程度呢?最小也不会比用最小生成树算法求得的树中的最大权值小。
所以,这个题用最小生成树算法求出最大权值后,再求有限制的最大生成树即可。
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxe=200005;
const int maxv=100005;
int V,E;
struct edge
{
int u,v,cost;
};
edge es[maxe];
int par[maxv];
void init(int n)
{
for(int i=1;i<=n;i++)
{
par[i]=i;
}
}
int find(int x)
{
if(par[x]==x) return x;
else return par[x]=find(par[x]);
}
bool same(int x,int y)
{
return find(x)==find(y);
}
void unit(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx==fy) return ;
else
{
par[fx]=fy;
}
}
bool cmp1(const edge& e1,const edge& e2)
{
return e1.cost<e2.cost;
}
bool cmp2(const edge& e1,const edge& e2)
{
return e1.cost>e2.cost;
}
int kur_maxv()
{
init(V);
sort(es,es+E,cmp2);
int ans=-1;
for(int i=E-1;i>=0;i--)
{
if(!same(es[i].u,es[i].v))
{
unit(es[i].u,es[i].v);
int tmp=es[i].cost;
if(tmp>ans || ans==-1)
ans=tmp;
}
}
return ans;
}
int main()
{
scanf("%d%d",&V,&E);
ll ans=0;
for(int i=0;i<E;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
es[i].u=x;
es[i].v=y;
es[i].cost=z;
}
int maxcost=kur_maxv();
init(V);
for(int i=0;i<E;i++)
{
if(!same(es[i].u,es[i].v) && es[i].cost<=maxcost)
{
unit(es[i].u,es[i].v);
ans+=es[i].cost;
}
}
printf("%lld\n",ans);
return 0;
}
51nod 1640 天气晴朗的魔法 (最小生成树)