• 【思维】三元环计数+鸽笼定理/贪心——LEETCODE 游乐园的游览计划 好题


    这题真的不错,有cf 的感觉

    三元环计数:这题要先把三元环统计出来 https://www.cnblogs.com/Dance-Of-Faith/p/9759794.html

    贪心:以v为顶点,把所有包含v的三元环统计出来,然后取权值最大的三个三元环t1,t2,t3,可以确定v为顶点的策略中至少有这三个中的一个(鸽笼定理,或者随便想想一定是这样)

       所以可以枚举前三个三元环,再枚举另一个三元环,设v有K个三元环,那么复杂度就是O(3K)

          由于所有三元环个数为O(m^1.5),所以总复杂度也是这个

    ps:在class内自定义sort的cmp函数,要用lambda表达式来写 关于lambda的使用以及捕获列表:https://blog.csdn.net/jlusuoya/article/details/75299096

    class Solution {
    public:
        #define N 10005
        vector<int>G[N];
        int id[N],rank[N],n,vis[N];
        int d[N],val[N];
        struct Circle{int a,b,c;};
        vector<Circle>s[N];
    
        inline int calc(Circle a,Circle b){
            int res=val[a.a]+val[a.b]+val[a.c]+val[b.a]+val[b.b]+val[b.c];
            if(a.a==b.a)res-=val[b.a];
            if(a.b==b.a)res-=val[b.a];
            if(a.c==b.a)res-=val[b.a];
    
            if(a.a==b.b)res-=val[b.b];
            if(a.b==b.b)res-=val[b.b];
            if(a.c==b.b)res-=val[b.b];
            
            if(a.a==b.c)res-=val[b.c];
            if(a.b==b.c)res-=val[b.c];
            if(a.c==b.c)res-=val[b.c];
            return res;
        }
    
        int maxWeight(vector<vector<int>>& edges, vector<int>& value) {
            n=value.size();    
            for(int i=0;i<n;i++)id[i]=i,val[i]=value[i];
            for(auto e:edges){
                int u=e[0],v=e[1];
                d[u]++,d[v]++;
            }
    
            sort(id,id+n,[&](int &a,int &b){
                if(d[a]==d[b])return a>b;
                return d[a]>d[b];
            });
            for(int i=0;i<n;i++)rank[id[i]]=i;
    
            for(auto e:edges){
                int u=e[0],v=e[1];
                if(rank[u]<rank[v])swap(u,v);
                G[u].push_back(v);
            }
            for(int i=0;i<n;i++){
                for(auto j:G[i])vis[j]=1;
                for(auto j:G[i])
                    for(auto k:G[j])
                        if(vis[k]==1){
                            Circle t=(Circle){i,j,k};
                            s[i].push_back(t);
                            s[j].push_back(t);
                            s[k].push_back(t);
                        }
                for(auto j:G[i])vis[j]=0;
            }
    
            int ans=0;
            for(int i=0;i<n;i++){
                sort(s[i].begin(),s[i].end(),[&](Circle &a,Circle &b){
                    int res1=val[a.a]+val[a.b]+val[a.c],res2=val[b.a]+val[b.b]+val[b.c];
                    return res1>res2;
                });
                int j=s[i].size();
                if(j>=1){
                    for(int k=0;k<j;k++)
                        ans=max(ans,calc(s[i][0],s[i][k]));
                }
                if(j>=2){
                    for(int k=0;k<j;k++)
                        ans=max(ans,calc(s[i][1],s[i][k]));
                }
                if(j>=3){       
                    for(int k=0;k<j;k++)
                        ans=max(ans,calc(s[i][2],s[i][k]));
                }
            }
    
            return ans;
        }
    };
  • 相关阅读:
    在Fragment中保存WebView状态
    Code First下迁移数据库更改
    脚本解决.NET MVC按钮重复提交问题
    1.1C++入门 未完待续。。。
    0.0C语言重点问题回顾
    12F:数字变换
    12G:忍者道具
    12D:迷阵
    12C:未名冰场
    12B:要变多少次
  • 原文地址:https://www.cnblogs.com/zsben991126/p/13040761.html
Copyright © 2020-2023  润新知