国王的礼物
微妙,题目很ok的表达了我想法
这个打法跟第k小生成树差不多
具体这题还是看题解。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 205;
const int M = 50005;
struct Edge
{
int u,v,g,s;
bool operator < (const Edge& p) const
{
return g < p.g;
}
}e[M];
int fa[N];
int tmp[N],id[M];
int t[N],kk;
int n,m,g,s;
bool flag;
vector<int> edge[N];
void del(int u,int k)
{
int len = edge[u].size();
int q = 0;
for(int i = 0;i < len; ++i)
if(edge[u][i] != k)
t[q++] = edge[u][i];
edge[u].clear();
for(int i = 0;i < q; ++i)
edge[u].push_back(t[i]);
}
int Find(int x)
{
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
void dfs(int u,int fa,int f)
{
if(u == f)
{
flag = true;
return;
}
int len=edge[u].size();
for(int i=0;i<len; ++i)
{
int p = edge[u][i];
int v = (e[p].u == u ? e[p].v : e[p].u);
if(v == fa) continue;
dfs(v,u,f);
if(flag == true)
{
if(kk==-1) kk = p;
else if(e[kk].s < e[p].s)
kk = p;
return;
}
}
}
int main()
{
freopen("gift.in","r",stdin);
freopen("gift.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&g,&s);
for(int i = 0;i < m; ++i)
{
scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].g,&e[i].s);
if(e[i].u == e[i].v)
{
i--;
m--;
}
}
for(int i = 1;i <= n; ++i)
{
fa[i] = i;
edge[i].clear();
}
sort(e,e + m);
ll ans = -1;
int l = 0;
for(int i = 0;i < m; ++i)
{
int u=e[i].u;
int v=e[i].v;
int fu=Find(u),fv = Find(v);
if(fu!=fv)
{
id[i] = l;
tmp[l++] = i;
fa[fu] = fv;
edge[u].push_back(i);
edge[v].push_back(i);
}
else
{
kk = -1;
flag = false;
dfs(u,-1,v);
if(kk != -1 && e[kk].s > e[i].s)
{
tmp[id[kk]]=i;
id[i]=id[kk];
del(e[kk].u,kk);
del(e[kk].v,kk);
edge[u].push_back(i);
edge[v].push_back(i);
}
}
if(l==n-1)
{
ll pg = -1,ps = -1;
for(int j = 0;j < l; ++j)
{
if(pg==-1||e[tmp[j]].g>pg) pg=e[tmp[j]].g;
if(ps==-1||e[tmp[j]].s>ps) ps=e[tmp[j]].s;
}
ll p=pg*g+ps*s;
if(ans == -1) ans = p;
else ans = min(ans,p);
}
}
printf("%lld\n",ans);
return 0;
}
再给出CF神仙代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct think{
ll x,y,a,b;
bool operator<(const think A)const{
return a<A.a;
}
}a[50005],q[205];
ll n,m,A,B,fa[205];
ll find(ll x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
int main(){
freopen("gift.in","r",stdin);
freopen("gift.out","w",stdout);
cin>>n>>m>>A>>B;
for(ll i=1;i<=m;i++){
cin>>a[i].x>>a[i].y>>a[i].a>>a[i].b;
}
sort(a+1,a+m+1);
ll ans=0x7fffffffffffffff;
for(ll i=1,t=0,s;i<=m;i++){
q[++t]=a[i];
s=0;
for(ll j=t-1;j&&q[j+1].b<q[j].b;j--) swap(q[j],q[j+1]);
for(ll j=1;j<=n;j++) fa[j]=j;
for(ll j=1,x,y;s<n-1&&j<=t;j++)
if((x=find(q[j].x))!=(y=find(q[j].y))) fa[x]=y,q[++s]=q[j];
if(s==n-1) ans=min(ans,1ll*A*a[i].a+1ll*B*q[s].b);
t=s;
}
cout<<(ans==0x7fffffffffffffff ? -1:ans);
return 0;
}