转眼,时间回到了半个月前,省赛选拔之前,也就差不多是我开始自己博客生涯的时间。不觉之间,回忆的时光已经一年过去了。感慨自己入坑acm一年以来的碌碌无为,不如从现在开始奋斗吧,亡羊补牢为时不晚,关键就是要有决心与毅力。
这是一道半月前遗留的未ac问题,源于2013陕西首届省赛
思路:刚拿到题目的一瞬间,感觉有种二分图匹配的味道,瞬间心存戒意。
不过后来耐心读题后发现,并不一定需要两两成对报名,而且,报名顺序甚至都没有限制,退化为无向图。于是,该题瞬间变成了最小生成树的变体,即最大生成树问题,直接强行开Kruskal,即排序+并查集。
不过莫名其妙TLE,考虑到O(eloge)的时间复杂度按道理是不会有问题的
然而殊不知数组越界这一未定义不可知因素可能返回各种玄学的结果,所以还是细节决定成败啊
/*
Author:Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
typedef struct DISCOUNT
{
int a, b, r;
}Discount;
Discount d[maxn];
int pre[maxn];
int finds(int x)
{
int r = x;
while(pre[r]!=r)
{
r = pre[r];
}
int i=x ,j;
while(pre[i]!=r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void join(int x,int y)
{
int fx = finds(x);
int fy = finds(y);
if(fx > fy)
{
int temp = fx;
fx = fy;
fy = temp;
}
if(fx!=fy)
{
pre[fy] = fx;
}
}
bool cmp(const Discount &x, const Discount &y)
{
return x.r>y.r;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int m,n,k,x;
scanf("%d%d%d%d",&m,&n,&k,&x);
for(int i=1;i<=m+n;i++)
{
pre[i] = i;
}
for(int i=0;i<x;i++)
{
scanf("%d%d%d",&d[i].a,&d[i].b,&d[i].r);
}
sort(d,d+x,cmp);
int dount = 0;
for(int i=0;i<x;i++)
{
int pa = finds(d[i].a);
int pb = finds(d[i].b+m);
if(pa!=pb)
{
join(pa,pb);
dount += d[i].r;
}
}
int sum = (m + n) * k - dount;
printf("%d\n",sum);
}
return 0;
}