51nod-1640--天气晴朗的魔法(简单最小生成树)

1640 天气晴朗的魔法

题目来源: 原创

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题

这样阴沉的天气持续下去,我们不免担心起他的健康。

51nod魔法学校近日开展了主题为“天气晴朗”的魔法交流活动。

N名魔法师按阵法站好,之后选取N - 1条魔法链将所有魔法师的魔力连接起来,形成一个魔法阵。

魔法链是做法成功与否的关键。每一条魔法链都有一个魔力值V,魔法最终的效果取决于阵中所有魔法链的魔力值的和。

由于逆天改命的魔法过于暴力,所以我们要求阵中的魔法链的魔力值最大值尽可能的小,与此同时,魔力值之和要尽可能的大。

现在给定魔法师人数N,魔法链数目M。求此魔法阵的最大效果。

Input

两个正整数N,M。(1 <= N <= 10^5, N <= M <= 2 * 10^5)

接下来M行,每一行有三个整数A, B, V。(1 <= A, B <= N, INT_MIN <= V <= INT_MAX)

保证输入数据合法。

Output

输出一个正整数R,表示符合条件的魔法阵的魔力值之和。

Input示例

4 6
1 2 3
1 3 1
1 4 7
2 3 4
2 4 5
3 4 6

Output示例

12
 
 

分析:

其实这个题目读懂题目后很好做,求的是在最大值最小的前提下,魔法值之和最大的生成树

其实就是先求出最小生成树之后,记录一下生成树中的最大值,然后求边权最大值为这个值的最大生成树

注意51行到53行,一定要进行这一步处理,不然会WA。。。。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int MAXN=100000+30;
  4 const int MAXM=2*MAXN+30;
  5 int f[MAXN];
  6 struct edge
  7 {
  8     int u,v;
  9     long long w;
 10 }e[MAXM];
 11 int tot;
 12 void addedge(int v,int u,int w)
 13 {
 14     e[tot].v=v;
 15     e[tot].u=u;
 16     e[tot].w=w;
 17     tot++;
 18 }
 19 int fin(int x)
 20 {
 21     if(f[x]==-1)
 22         return x;
 23     else{
 24         f[x]=fin(f[x]);
 25         return f[x];
 26     }
 27 }
 28 bool cmp(edge a,edge b)
 29 {
 30     return a.w<b.w;
 31 }
 32 long long kru(int n)
 33 {
 34     memset(f,-1,sizeof(f));
 35     sort(e,e+tot,cmp);
 36     long long num=0,ans=0;
 37     int u,v,w;
 38     int i;
 39     for(i=0;i<tot;i++){
 40         u=e[i].u,v=e[i].v,w=e[i].w;
 41         int t1=fin(u);
 42         int t2=fin(v);
 43         if(t1!=t2){
 44             num++;
 45             f[t2]=t1;
 46         }
 47         if(num==n-1) break;
 48     }
 49     num=0;
 50     memset(f,-1,sizeof(f));
 51     while(e[i].w==e[i+1].w){
 52         i++;
 53     }
 54     for(;i>=0;i--){
 55         u=e[i].u,v=e[i].v,w=e[i].w;
 56         int t1=fin(u);
 57         int t2=fin(v);
 58         if(t1!=t2){
 59             num++;
 60             ans+=w;
 61             f[t2]=t1;
 62         }
 63         if(num==n-1) break;
 64     }
 65     if(num<n-1) return -1;
 66     else return ans;
 67 }
 68 int main()
 69 {
 70     //freopen("data.in","r",stdin);
 71     int n,m;
 72     int a,b;
 73     long long v;
 74     tot=0;
 75     scanf("%d%d",&n,&m);
 76     for(int i=0;i<m;i++){
 77         scanf("%d%d%lld",&a,&b,&v);
 78         addedge(a,b,v);
 79     }
 80     //printf("%lld\n",kru(n));
 81     cout<<kru(n)<<endl;
 82 }
 83 
View Code
posted @ 2017-04-19 22:21  Pic  阅读(194)  评论(0编辑  收藏  举报