COGS——T 1578. 次小生成树初级练习题

http://www.cogs.pro/cogs/problem/problem.php?pid=1578

☆   输入文件:mst2.in   输出文件:mst2.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

求严格次小生成树

【输入格式】

第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。

【输出格式】

包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)

【样例输入】

5 6

1 2 1

1 3 2

2 4 3

3 5 4

3 4 3

4 5 6

【样例输出】

11

【提示】

数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。

【来源】

bzoj。。。

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 
 7 const int INF(0x7fffffff);
 8 const int N(300005);
 9 struct Edge
10 {
11     int u,v,w;
12     bool operator < (const Edge &x) const
13     {
14         return w<x.w;
15     }
16 }edge[N];
17 int n,m,fa[N],used[N];
18 
19 int find(int x)
20 {
21     return x==fa[x]?x:x=find(fa[x]);
22 }
23 
24 inline int k(int cant)
25 {
26     int ret=0,cnt=0,fx,fy;
27     for(int i=1;i<=n;i++) fa[i]=i;
28     for(int i=1;i<=m;i++)
29     {
30         if(i==cant) continue;
31         fx=find(edge[i].u),fy=find(edge[i].v);
32         if(fa[fx]==fy) continue;
33         fa[fx]=fy;
34         ret+=edge[i].w;
35         if(++cnt==n-1) return ret;
36     }
37     return INF;
38 }
39 
40 inline void read(int &x)
41 {
42     register char ch=getchar();x=0;
43     for(;ch>'9'||ch<'0';) ch=getchar();
44     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
45 }
46 int AC()
47 {
48     freopen("mst2.in","r",stdin);
49     freopen("mst2.out","w",stdout);
50     
51     read(n),read(m);
52     for(int i=1;i<=m;i++)
53     {
54         read(edge[i].u);
55         read(edge[i].v);
56         read(edge[i].w);
57     }
58     sort(edge+1,edge+m+1);
59     int Fir_min=0,Sec_min=INF,tmp,cnt=0;
60     for(int i=1;i<=n;i++) fa[i]=i;
61     for(int fx,fy,i=1;i<=m;i++)
62     {
63         fx=find(edge[i].u);
64         fy=find(edge[i].v);
65         if(fa[fx]==fy) continue;
66         fa[fx]=fy;
67         Fir_min+=edge[i].w;
68         used[++cnt]=i;
69         if(cnt==n-1) break;
70     }
71     for(int i=1;i<=cnt;i++)
72     {
73         tmp=k(used[i]);
74         if(tmp>Fir_min&&tmp<Sec_min)
75             Sec_min=tmp;
76     }
77     printf("%d\n",Sec_min);
78     return 0;
79 }
80 
81 int I_want_AC=AC();
82 int main(){;}

 

posted @ 2017-08-25 14:17  Aptal丶  阅读(216)  评论(0编辑  收藏  举报