ACdream 1135 MST

MST

Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

Problem Description

Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together.  A single graph can have many different spanning trees. We can also assign a weight to each edge, which is a number representing how unfavorable it is, and use this to assign a weight to a spanning tree by computing the sum of the weights of the edges in that spanning tree. A minimum spanning tree (MST) is then a spanning tree with weight less than or equal to the weight of every other spanning tree.
------ From wikipedia
Now we make the problem more complex. We assign each edge two kinds of
weight: length and cost. We call a spanning tree with sum of length less
than or equal to others MST. And we want to find a MST who has minimal
sum of cost.

Input

There are multiple test cases.
The first line contains two integers N and M indicating the number of vertices and edges in the gragh.
The next M lines, each line contains three integers a, b, l and c indicating there are an edge with l length and c cost between a and b.

1 <= N <= 10,000
1 <= M <= 100,000
1 <= a, b <= N
1 <= l, c <= 10,000

Output

For each test case output two integers indicating the sum of length and cost of corresponding MST.
If you can find the corresponding MST, please output "-1 -1".

Sample Input

4 5
1 2 1 1
2 3 1 1
3 4 1 1
1 3 1 2
2 4 1 3

Sample Output

3 3

Source

dut200901102

Manager

dut200901102

解题:是的,没错,就是MST,只是是双关键字排序

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 500010;
 5 struct arc{
 6     int u,v,length,cost;
 7     bool operator<(const arc &rhs)const{
 8         if(length == rhs.length) return cost < rhs.cost;
 9         return length < rhs.length;
10     }
11 }e[maxn];
12 int uf[maxn];
13 int Find(int x){
14     if(x != uf[x]) uf[x] = Find(uf[x]);
15     return uf[x];
16 }
17 int main(){
18     int n,m;
19     while(~scanf("%d%d",&n,&m)){
20         for(int i = 0; i < m; ++i)
21         scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].length,&e[i].cost);
22         for(int i = 0; i <= n; ++i) uf[i] = i;
23         sort(e,e + m);
24         LL length = 0,cost = 0,cnt = 0;
25         for(int i = 0; i < m && cnt + 1 < n; ++i){
26             int u = Find(e[i].u);
27             int v = Find(e[i].v);
28             if(u == v) continue;
29             uf[u] = v;
30             length += e[i].length;
31             cost += e[i].cost;
32             ++cnt;
33         }
34         if(cnt + 1 == n) printf("%lld %lld\n",length,cost);
35         else puts("-1 -1");
36     }
37     return 0;
38 }

时间: 2024-10-24 06:37:33

ACdream 1135 MST的相关文章

ACdream 1135(MST-最小生成树边上2个值,维护第一个最小的前提下让另一个最小)

F - MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices to

ACDREAM 1726 A Math game(折半枚举+hash)

题目链接: http://acdream.info/problem?pid=1726 题意: 给定n 个数,和一个数看,判断k能否由其中的任意个数的和组成. 分析: 因为n最大为40,暴力枚举所有的情况 复杂度为 2^40 肯定TLE ,然后就想到了折半枚举 分成两半,先处理前n/2个数的组合的情况 ,把所得结果哈希一下,然后再枚举后一半 的所有情况,然后在哈希表里查找.时间复杂度为 O(2^(N/2)); 代码如下: #include <stdio.h> #include <iostr

Acdream 1117 Number theory(莫比乌斯反演)

题目链接: http://acdream.info/problem?pid=1114 题意: 给定一个序列,求序列中互质的数的对数. 分析: 我们设f(d) 表示gcd恰好为d的数的个数,F(d)表示gcd为d的倍数的个数 因此,F(d) = sigma (f(n))  (n%d==0) f(n)= sigma( mu[d]*F[n/d] ) (n%d==0); 因此我们先统计出每个数出现的频数num; 然后用cnt[i]表示i的倍数的个数. F(i) = C(cnt[i],2); 我们最终要求

ACdream原创群赛(16) F

MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices togeth

poj1789 MST 读题生涯永不停歇

题目: 链接在此 1.图论刷刷乐#1的第一题,无奈看了好长时间题目还是看不懂= =,明知是最水的题目 2.搜懂题目后,比较裸的MST,但还是决定写个题解,虽然没什么可说的,只是来警戒自己,还是要努力读题,YY大法,这也是水平的一个体现! #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include &

求最小原根 51nod 1135

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135 代码 // the smallest primitive root of prime P #include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; long long N; i

【BZOJ 2654】 MST

2654: tree Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V,E,need分别表示点数,边数和需要的白色边数. 接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色). Output 一行表示所求生成树的边权和. V<=50000,E<=100000,所有数据边权为[1,100]中的正整数. Sample Input 2 2 1 0 1

POJ 1679 The Unique MST(次短生成树)

Language: Default The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29098   Accepted: 10404 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider

HDU 4126 Genghis Khan the Conqueror (树形DP+MST)

题意:给一图,n个点,m条边,每条边有个花费,给出q条可疑的边,每条边有新的花费,每条可疑的边出现的概率相同,求不能经过原来可疑边 (可以经过可疑边新的花费构建的边),注意每次只出现一条可疑的边,n个点相互连通的最小花费的期望. 析:要想连通先让他们连通起来,先构造出一个MST,然后再暴力,如果这个边不在这里面,那么花费不变,如果在里面,那我们需要知道是用原来的边最少, 还是再找一条边使他们连通起来,这里就要先预处理了,dp[i]j[i] 表示 左边的那个一半 i 和 右边那一半 j 的最长距离