标签:cond sort ring print cpp har signed += ==
https://vjudge.net/problem/UVALive-6807
蛮神奇的题目,考虑选的边的在原图中的补集,会发现,没有环出现,那么这是一张无向无环图,也就是一棵树.转化为\(\sum w_i - \sum k_i\)
\(k\)为在树上的边权,所以直接求一发最大生成树就可以了.
#include <set>
#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(i,x,p) for(int i = x;i <= p;++ i)
#define sep(i,x,p) for(int i = x;i >= p;-- i)
#define ull unsigned long long
#define ll long long
#define gc getchar()
#define pc putchar
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int maxN = 10000 + 7;
const int maxM = 200000 + 7;
int f[maxN];
inline int read() {
int x = 0,f = 1;char c = gc;
while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}
return x * f;
}
int print(long long x) {
if(x < 0) pc('-'),x = -x;
if(x >= 10) print(x / 10);
pc(x % 10 + '0');
return 0;
}
struct Node {
int u , v, w;
bool operator < (const Node&x) const{return w > x.w;}
}Q[maxM];
int n , m;
bool vis[maxM];
int find(int x) {return f[x] == x ? x : find(f[x]);}
void unit(int u,int v) {int fu = find(u),fv = find(v);f[fu] = fv;}
ll krukal() {
rep(i , 1, n) f[i] = i;
int k = 0;
ll sum = 0;
sort(Q + 1,Q + m + 1);
rep(i , 1, m) {
int v = Q[i].v,u = Q[i].u,w = Q[i].w;
int fv = find(v),fu = find(u);
if(fv == fu) continue;
unit(fv,fu);
vis[i] = true;k ++;sum += w;
if(k == n - 1) break;
}
return sum;
}
int main() {
int T = read();
for(int i = 1;i <= T;++ i) {
memset(vis , 0, sizeof(vis));
n = read(), m = read();
ll sum = 0;int ans = 0;
rep(j , 1, m) Q[j] = (Node) {read(),read(),read()} , sum += Q[j].w;
sum -= krukal();
rep(j , 1, m) if(!vis[j]) ans = max(ans , Q[j].w);
printf("Case #%d: %lld %d\n",i,sum,ans);
}
return 0;
}
标签:cond sort ring print cpp har signed += ==
原文地址:https://www.cnblogs.com/gzygzy/p/10145428.html