1 条题解

  • 0
    @ 2025-8-24 21:41:44

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar D10s
    **

    搬运于2025-08-24 21:41:44,当前版本为作者最后更新于2017-10-31 10:00:49,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    本题也可采取图论做法,相当于是双边权情况下的最小生成树。

    因为题目保证t<T,所以边权取T的边不可能超过k条(超过的拿t替换更优)。

    这样我们只要在克鲁斯卡尔的时候前k条边用T扩展,后n-1-k条用t即可,记录最大边权。

    #include<cstdio>
    #include<queue>
    using namespace std;
    struct edge{
        int u,v,t,T;
    }e;
    struct cmp1{bool operator () (edge a,edge b) {return a.t>b.t;} };
    struct cmp2{bool operator () (edge a,edge b) {return a.T>b.T;} };
    priority_queue<edge,vector<edge>,cmp1> q1;
    priority_queue<edge,vector<edge>,cmp2> q2;
    int fa[10005];
    int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
    int max(int x,int y) {return x>y?x:y;}
    int main()
    {
        int n,m,k;
        scanf("%d%d%d",&n,&k,&m);
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int j=1;j<=m;j++)
        {
            scanf("%d%d%d%d",&e.u,&e.v,&e.T,&e.t);
            q1.push(e);q2.push(e);
        }
        m=0;int ans=0;
        while(q2.size()&&m<k)
        {
            e=q2.top();q2.pop();
            int x=find(e.u),y=find(e.v);
            if(x==y) continue;
            ans=max(ans,e.T);
            m++;
            fa[x]=y;
        }
        while(q1.size()&&m<n-1)
        {
            e=q1.top();q1.pop();
            int x=find(e.u),y=find(e.v);
            if(x==y) continue;
            ans=max(ans,e.t);
            m++;
            fa[x]=y;
        }
        printf("%d\n",ans);
        return 0;
    }
    
    • 1

    信息

    ID
    1870
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者