luogu诚不欺我
果然——
今天大大爆炸
本打算着能T1T2能A掉
T4能QJ几个特判的测试点
结果最有把握的两个题
全部挂零儿
然后T4唯二的两个NO的点
完美的落在了我特判的YES上
于是本来就可怜巴巴的10分都没了
A.走廊泼水节
一句话题意
给个树n-1条边
让加边加成完全图
并且保证原树仍然是最小生成树
code
#include
#include
#include
#include
using namespace std;
inline int read(){
int x = 0, w = 1;
char ch;
for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return x * w;
}
const int maxn = 6007;
struct node{
int to, from, w;
inline bool operator < (const node &x)const{
return w < x.w;
}
}edge[maxn << 1];
int fa[maxn], size[maxn];
inline int find(int x){
if(fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
int n;
inline void kruskal(){
int ans = 0;
sort(edge + 1, edge + n);
for(int i = 1; i < n; i++){
int x = edge[i].from;
int y = edge[i].to;
int w = edge[i].w;
int xx = find(x);
int yy = find(y);
fa[xx] = yy;
ans += (size[yy] * size[xx] - 1) * (w + 1);
size[yy] += size[xx];
}
cout << ans << endl;
}
signed main(){
int t = read();
while(t--){
memset(fa, 0, sizeof fa);
memset(size, 0, sizeof size);
n = read();
for(int i = 1; i <= n; i++)
fa[i] = i, size[i] = 1;
for(int i = 1; i < n; i++){
edge[i].from = read();
edge[i].to = read();
edge[i].w = read();
}
kruskal();
/*
for(int i = 1; i <= n ;i++)
cout << size[i] << " ";
cout << endl;
*/
}
return 0;
}
B.Max Flow
题意
农场主约翰在他的N (2≤N≤50,000)个牛棚间安装了N-1条管道去运输牛奶,每个管道连接两个牛棚,每个牛棚都用管道直接或间接连接。
约翰在K(1≤K≤100,000)对牛棚间挤奶。假设约翰在第i对牛棚间挤奶,两牛棚分别是si,ti,这样挤出的牛奶将会经过si到ti间(包括端点)的每一个牛棚一次,在约翰挤完K对牛棚间的牛奶后,请问运输过牛奶次数最多的牛棚的运送次数是多少?
solution
树上差分裸题
板子挂了
code
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
int x = 0, w = 1;
char ch = getchar();
for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return x * w;
}
const int maxn = 100010;
struct node{
int to, nxt;
}edge[maxn << 1];
int head[maxn << 1], tot;
inline void add(int u, int v){
edge[++tot].to = v;
edge[tot].nxt = head[u];
head[u] = tot;
}
int n, k;
int dep[maxn], fa[maxn][50];
inline void dfs(int u){
dep[u] = dep[fa[u][0]] + 1;
for(int i = 1; (1 << i) <= n; i++)
fa[u][i] = fa[fa[u][i - 1]][i - 1];
for(int i = head[u]; i; i = edge[i].nxt){
int v = edge[i].to;
if(v == fa[u][0]) continue;
fa[v][0] = u;
dfs(v);
}
}
inline int lca(int u, int v){
if(dep[u] < dep[v]) swap(u, v);
int tmp = dep[u] - dep[v], k = 0;
while(tmp){
if(tmp & 1)
u = fa[u][k];
tmp >>= 1;
k++;
}
if(u == v) return u;
for(int i = 20; i >= 0; i--){
if(fa[u][i] != fa[v][i]){
u = fa[u][i];
v = fa[v][i];
}
}
return fa[u][0];
}
int a[maxn];
inline void solve(int u){
for(int i = head[u]; i; i = edge[i].nxt){
int v = edge[i].to;
if(v == fa[u][0]) continue;
solve(v);
a[u] += a[v];
}
}
int ans = 0;
signed main(){
n = read(), k = read();
for(int i = 1; i <= n - 1; i++){
int u = read(), v = read();
add(u, v);
add(v, u);
}
dfs(1);
for(int i = 1; i <= k; i++){
int u = read(), v = read();
a[u]++;
a[v]++;
a[lca(u, v)]--;
a[fa[lca(u, v)][0]]--;
}
solve(1);
for(int i = 1; i <= n; i++)
ans = max(ans, a[i]);
cout << ans << '\n';
return 0;
}