2018-Sp28-lyk/I
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include<bits/stdc++.h>
#define maxn 1200
using namespace std;
typedef unsigned int uint;
typedef pair<uint, uint> puu;
vector<puu> G[maxn];
vector<uint> A[maxn];
puu f[maxn];
uint d[maxn] = {0, 1}, A_size;
void dfs(uint u){
for(puu p: G[u]){
uint v = p.first, w = p.second;
if(d[v] == 0){
d[v] = d[u] + 1;
f[v] = puu(u, w);
dfs(v);
}
else if(d[v] > d[u]){
A[A_size].push_back(w);
uint p = v;
while(p != u){
A[A_size].push_back(f[p].second);
p = f[p].first;
}
A_size += 1;
}
}
}
void merge(vector<uint> &A, const vector<uint> &B, uint k){
priority_queue<puu> q;
for(uint x : A) q.push(puu(x + B[0], 0));
A.clear();
for(int i = 0; i < (int)k; i += 1){
if(q.empty()) break;
puu p = q.top();
q.pop();
A.push_back(p.first);
if(p.second + 1 < B.size())
q.push(puu(p.first + B[p.second + 1] - B[p.second], p.second + 1));
}
}
void merge(int l, int r, uint k){
if(l == r) return;
int m = (l + r) >> 1;
merge(l, m, k);
merge(m + 1, r, k);
merge(A[l], A[m + 1], k);
}
int main(){
int n, m, t = 0;
while(scanf("%d %d", &n, &m) == 2){
for_each(G + 1, G + n + 1, [](vector<puu> &v)->void{v.clear();});
fill(d + 2, d + n + 1, 0);
for_each(A, A + m - n + 2, [](vector<uint> &v)->void{v.clear();});
A[0].push_back(0);
uint s = 0;
for(int i = 0; i < m; i += 1){
uint x, y, z;
scanf("%u %u %u", &x, &y, &z);
G[x].push_back(puu(y, z));
G[y].push_back(puu(x, z));
s += z;
}
A_size = 1;
dfs(1);
uint k;
scanf("%u", &k);
for_each(A + 1, A + m - n + 2, [](vector<uint> &v)->
void{sort(v.begin(), v.end(), greater<uint>());});
merge(0, m - n + 1, k);
uint ans = 0;
for(uint i = 0; i < k && i < A[0].size(); i += 1)
ans += (i + 1) * (s - A[0][i]);
printf("Case #%d: %u\n", t += 1, ans);
}
}
}}}
#include<bits/stdc++.h>
#define maxn 1200
using namespace std;
typedef unsigned int uint;
typedef pair<uint, uint> puu;
vector<puu> G[maxn];
vector<uint> A[maxn];
puu f[maxn];
uint d[maxn] = {0, 1}, A_size;
void dfs(uint u){
for(puu p: G[u]){
uint v = p.first, w = p.second;
if(d[v] == 0){
d[v] = d[u] + 1;
f[v] = puu(u, w);
dfs(v);
}
else if(d[v] > d[u]){
A[A_size].push_back(w);
uint p = v;
while(p != u){
A[A_size].push_back(f[p].second);
p = f[p].first;
}
A_size += 1;
}
}
}
void merge(vector<uint> &A, const vector<uint> &B, uint k){
priority_queue<puu> q;
for(uint x : A) q.push(puu(x + B[0], 0));
A.clear();
for(int i = 0; i < (int)k; i += 1){
if(q.empty()) break;
puu p = q.top();
q.pop();
A.push_back(p.first);
if(p.second + 1 < B.size())
q.push(puu(p.first + B[p.second + 1] - B[p.second], p.second + 1));
}
}
void merge(int l, int r, uint k){
if(l == r) return;
int m = (l + r) >> 1;
merge(l, m, k);
merge(m + 1, r, k);
merge(A[l], A[m + 1], k);
}
int main(){
int n, m, t = 0;
while(scanf("%d %d", &n, &m) == 2){
for_each(G + 1, G + n + 1, [](vector<puu> &v)->void{v.clear();});
fill(d + 2, d + n + 1, 0);
for_each(A, A + m - n + 2, [](vector<uint> &v)->void{v.clear();});
A[0].push_back(0);
uint s = 0;
for(int i = 0; i < m; i += 1){
uint x, y, z;
scanf("%u %u %u", &x, &y, &z);
G[x].push_back(puu(y, z));
G[y].push_back(puu(x, z));
s += z;
}
A_size = 1;
dfs(1);
uint k;
scanf("%u", &k);
for_each(A + 1, A + m - n + 2, [](vector<uint> &v)->
void{sort(v.begin(), v.end(), greater<uint>());});
merge(0, m - n + 1, k);
uint ans = 0;
for(uint i = 0; i < k && i < A[0].size(); i += 1)
ans += (i + 1) * (s - A[0][i]);
printf("Case #%d: %u\n", t += 1, ans);
}
}