思路:
我们考虑有最小生成树得到最小生成树
我们一条一条边加进边集,然后每次重新做一遍最小生成树。
时间复杂度:
O
(
n
m
)
O(nm)
O(nm)(排序时间是n,用插入排序)
c o d e code code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n, m, top, st[1010100];
long long wG, wS, ans=1e18;
struct node
{
long long x, y, g, s;
}a[1010100];
long long fa[1010100];
long long find(long long x)
{
if(fa[x]==x)
return x;
return fa[x]=find(fa[x]);
}
bool cmp(node x, node y)
{
return x.g<y.g;
}
int main()
{
scanf("%lld%lld%lld%lld", &n, &m, &wG, &wS);
for(long long i=1; i<=m; i++)
scanf("%lld%lld%lld%lld", &a[i].x, &a[i].y, &a[i].g, &a[i].s);
sort(a+1, a+1+m, cmp);
for(long long i=1; i<=m; i++)
{
long long j;
for(j=1; j<=n; j++)
fa[j]=j;
for(j=top; j>=1; j--)
if(a[st[j]].s>a[i].s)
st[j+1]=st[j];
else break;
top++;
st[j+1]=i;
long long maxg=0, maxs=0, sum=0;
for(j=1; j<=top; j++)
{
long long fx=find(a[st[j]].x), fy=find(a[st[j]].y);
if(fx!=fy)
{
fa[fy]=fx;
maxg=max(a[st[j]].g, maxg);
maxs=max(a[st[j]].s, maxs);
st[++sum]=st[j];
}
}
if(sum==n-1)
ans=min(ans, wG*maxg+wS*maxs);
top=sum;
}
if(ans==1e18)
printf("-1");
else
printf("%lld", ans);
return 0;
}