码迷,mamicode.com
首页 > 其他好文 > 详细

第 2 场周赛

时间:2021-06-06 19:26:45      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:class   最优   必须   思路   jks   --   size   math   heap   

3626. 三元一次方程

签到。

暴力思路是三重枚举,可优化至两重枚举。

int n;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        bool ok=false;
        
        for(int i=0;3*i<=n && !ok;i++)
            for(int j=0;3*i+5*j<=n && !ok;j++)
            {
                int k=n-3*i-5*j;
                if(k % 7 == 0)
                {
                    ok=true;
                    cout<<i<<‘ ‘<<j<<‘ ‘<<k/7<<endl;
                }
            }
        
        if(!ok) puts("-1");
    }
    //system("pause");
    return 0;
}

3627. 最大差值

贪心。

\(k\)次操作,每次可选定一对元素\((a_i,a_j)\),使得其中一个增加\(c\),另一个减少\(c\)\(0 \le c \le a_i\)

最小值最终一定为\(0\),最大值初值可设为序列中的最大值。

显然每次操作的\(c\)越大越好,于是\(c\)取除去最大值后序列中的前\(k\)大值即为最优。

const int N=2e5+10;
int a[N];
int n,k;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>k;

        for(int i=0;i<n;i++) cin>>a[i];

        sort(a,a+n,greater<int>());

        LL res=a[0];
        for(int i=1;i<=k;i++) res+=a[i];
        cout<<res<<endl;
    }
    //system("pause");
    return 0;
}

3628. 边的删减

  • 对某一个点\(i\),若\(d_i\)不变,则在最短路树中从\(1\)\(i\)的所有边必须被保留。
  • 每保留一条边,可以让一个点的\(d_i\)保持不变。
  • \(dist[u]+w(u\rightarrow v) = dist[v]\)说明是最短路树上的边。

若想\(d_i\)保持不变的点尽量多,从最短路树的根节点\(1\)开始任意选一个包含\(k\)条边的连通块即可,这样可使得\(k+1\)个点的\(d_i\)保持不变。

于是记录最短路树中的所有边的编号,保留出队的前\(k\)条边存入\(res\)数组中即可。

Dijkstra算法每个节点仅出队一次,出队顺序满足拓扑序,于是优先出队的前\(k\)条边一定是属于同一个连通块的。

const int N=1e5+10;
struct Node
{
    int v;
    LL dis;
    int idx;
    bool operator>(const Node &W) const
    {
        return dis > W.dis;
    }
};
vector<Node> g[N];
LL dist[N];
bool vis[N];
int n,m,k;
vector<int> res;

void dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    priority_queue<Node, vector<Node>, greater<Node>> heap;
    heap.push({1,0,0});

    while (heap.size())
    {
        int t=heap.top().v, idx=heap.top().idx;
        heap.pop();

        if (vis[t]) continue;
        vis[t] = true;
        
        if(idx && res.size() < k) res.pb(idx);

        for(int i=0;i<g[t].size();i++)
        {
            int j = g[t][i].v, w=g[t][i].dis, idx=g[t][i].idx;
            if (dist[j] > dist[t] + w)
            {
                dist[j] = dist[t] + w;
                heap.push({j, dist[j], idx});
            }
        }
    }
}

int main()
{
    cin>>n>>m>>k;

    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        g[a].pb({b,c,i});
        g[b].pb({a,c,i});
    }
    
    dijkstra();
    
    cout<<res.size()<<endl;
    
    for(auto &t : res)
        cout<<t<<‘ ‘;
    cout<<endl;

    //system("pause");
    return 0;
}

第 2 场周赛

标签:class   最优   必须   思路   jks   --   size   math   heap   

原文地址:https://www.cnblogs.com/fxh0707/p/14855049.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!