CF76A GIFT

国王的礼物

这里写图片描述
这里写图片描述

微妙,题目很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;
}

猜你喜欢

转载自blog.csdn.net/beautiful_cxw/article/details/81017514