zoukankan      html  css  js  c++  java
  • 【BZOJ3714】Kuglarz(PA2014)-最小生成树

    测试地址:Kuglarz
    做法:本题需要用到最小生成树。
    看到上面大家肯定会非常疑惑,这个题目是怎么转化成最小生成树的呢?且听我慢慢道来。
    我们尝试找到得到Ai(即第i个杯子有没有球)的充要条件,答案显然是存在一些选定的区间的异或值等于Ai。我们把这个条件转化,注意到,若把区间[i,j]转化成无向边(i1,j),那么这个条件就相当于能通过选定的边从点i1走到点i。为什么能这样转化?可以把走的过程看成,每走一条边就异或上这条边表示的区间,那么最后肯定就只剩下Ai了。
    那么我们知道能得到Ai的条件就是点i1和点i连通,那么要找到所有的Ai,就是让点0到点N都连通,并且所需代价最小,这显然做一个最小生成树就行了。因为边数很大,不能使用Kruskal算法,要用Prim算法来求。
    (啊,终于找到这题了,很久之前我在博客里写过这题的思路,但是没找到原题,现在行了)
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll inf=1000000000ll*1000000000ll;
    int n;
    ll ans=0,g[2010][2010],dis[2010];
    bool vis[2010]={0};
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=i;j<=n;j++)
                scanf("%lld",&g[i][j+1]),g[j+1][i]=g[i][j+1];
    
        vis[1]=1;
        for(int i=2;i<=n+1;i++)
            dis[i]=g[1][i];
        ans=0;
        for(int i=2;i<=n+1;i++)
        {
            ll mn=inf;
            int x;
            for(int j=1;j<=n+1;j++)
                if (!vis[j]&&dis[j]<mn)
                {
                    mn=dis[j];
                    x=j;
                }
            vis[x]=1;
            ans+=mn;
            for(int j=1;j<=n+1;j++)
                dis[j]=min(dis[j],g[x][j]);
        }
        printf("%lld",ans);
    
        return 0;
    }
  • 相关阅读:
    学会Git玩转Github笔记(一)——Github基本概念 & 仓库管理
    Github 入门基本操作
    Struts2拦截器浅析
    SSH(Struts2+Spring4+Hibernate4)框架教程之配置篇
    Spring 体系结构
    Ubuntu启动sshd服务
    jquery ajax/post 请求 案例
    Elasticsearch 配置
    Jenkins安装与配置
    解决Ubuntu环境变量错误导致无法正常登录  (command 'xxx' is available in bin ls)
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793406.html
Copyright © 2011-2022 走看看