codefroces 1023F

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Game_Acm/article/details/81839453

题目链接

题意:

有两家手机线路建设公司在抢生意(你就是其中一家,你的目标是将自己家的线路全部卖出去),另一家公司的线路建设以及价格已经被你的公司知道,而且你知道用户在选择建设线路时如果两家价钱相同会优先选择你的公司出售的线路,求你的公司最大利润,如果有些线路在竞争中没有被使用掉就可以天价卖掉(无穷无尽的天价),因为天价无法表示用-1代替

数据:

给定n,k,m表示有n个通信点需要连通你的公司准备了k条线路你的对手准备了m条线路,k行输入你公司的线路,m行输入对手公司的线路带价格

思路:

因为最终的线路连接一定是一个颗树,所以只需要n-1条边。又因为需要将本公司的k条线路全部卖出,所以本公司的k条线路需要全部使用,其他线路由另一家公司提供。为了将本公司的全部线路卖出,所以需要将那些不能融进树里的另一家公司线路全部竞争掉,将这些线路记录下来。那如何竞争掉另一家公司的线路呢?需要你将准备线路连通起来,连通起来自然要选择最短的路连接起来,所以我们需要建起一颗树,然后通过它们公共祖先得知它们如何连接,最后统计答案即可

C++代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
const int maxm = 1000010;
int n,k,m,tol,head[maxn],pre[maxn];
struct edge
{
    int to,cost,next;
}es[maxm];
void addedge( int u , int v , int w )
{
    es[tol].to = v;
    es[tol].cost = w;
    es[tol].next = head[u];
    head[u]  = tol++;
}
int Find( int x )
{
    return x==pre[x]?x:pre[x]=Find(pre[x]);
}
int a[maxn],b[maxn],val[maxn],cnt;
int f[maxn],d[maxn],res[maxn];
void dfs( int u )
{
    for ( int i=head[u] ; i!=-1 ; i=es[i].next )
    {
        int v = es[i].to;
        if ( v!=f[u] )
        {
            f[v] = u;
            d[v] = d[u]+1;
            dfs( v );
        }
    }
}
int main()
{
    tol = 0,memset ( head , -1 , sizeof(head) );
    scanf ( "%d%d%d" , &n , &k , &m );
    for ( int i=1 ; i<=n ; i++ ) pre[i] = i;
    for ( int i=1 ; i<=k ; i++ )
    {
        int u,v; scanf ( "%d%d" , &u , &v );
        pre[Find(u)] = Find(v);
        addedge( u , v , 0 );
        addedge( v , u , 0 );
    }
    for ( int i=1 ; i<=m ; i++ )
    {
        int u,v,w; scanf ( "%d%d%d" , &u , &v , &w );
        if ( Find(u)==Find(v) )
        {
            ++cnt;
            a[cnt] = u;
            b[cnt] = v;
            val[cnt] = w;
        }
        else
        {
            pre[Find(u)] = Find(v);
            addedge( u , v , 1 );
            addedge( v , u , 1 );
        }
    }
    dfs( 1 );
    for ( int i=1 ; i<=n ; i++ ) pre[i] = i;
    for ( int i=1 ; i<=cnt ; i++ )
    {
        int u = Find(a[i]);
        int v = Find(b[i]);
        while ( u!=v )
        {
            if ( d[u]>d[v] )
            {
                res[u] = val[i];
                pre[u] = Find( f[u] );
                u = pre[u];
            }
            else
            {
                res[v] = val[i];
                pre[v] = Find( f[v] );
                v = pre[v];
            }
        }
    }
    long long ans = 0;
    for ( int u=1 ; u<=n ; u++ )
    {
        for ( int i=head[u] ; i!=-1 ; i=es[i].next )
        {
            int v = es[i].to,w = es[i].cost;
            if ( v==f[u]&&w==0 )
            {
                if ( u==Find(u) )
                {
                    printf ( "-1\n" );
                    return 0;
                }
                ans += res[u];
            }
        }
    }
    printf ( "%I64d\n" , ans );
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Game_Acm/article/details/81839453