• 最大团&优化


    貌似咕了三个半月了(gym101915里一道),今天又遇到一道(cf1105E),就学了学惹。

    最大团定义:图上取尽可能多的点,这些点构成一个完全图。

    最大独立集:图上取尽可能多的点,任意两点间不连接。

    可以看出来   一个图的最大团==它的补图的最大独立集 叭

    那么我们可以搜索哇!(我不会搜索哇)

    一个最朴素的搜索思想:  维护几个点集,当前已选择的,可以选择的,然后每次从可选择的点集里选一个与当前已选择的点都有边的点加进来,然后更新可选择的点集。

    这个复杂度就比较恐怖哇

    简单的优化:对点排序,每次都选一个节点编号比当前点编号大的。可以参考一下wannafly winter camp 的小木棍那题

    剪枝一:如果当然已选点集大小+可选点集大小小于mx,return

    剪枝二:我们从后向前选取点,保存后面的答案,如果当前点集+ans[待选]小于mx,return

    其他的优化我也没看懂啊。。。

    附 1105 E的代码,我真是自闭了。我傻逼了 map.count(s)和 mp[s] 是不一样的、、、调了半个多小时没看出来。。注释掉的部分是输出答案找bug的o.o

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 map<string,int> mp;
     4 int n,m,op;string s;int cnt=-1;
     5 vector<int> v;
     6 bool g[50][50];
     7 int ans;int mx[50];int alt[50][50];
     8 //int cs[50];
     9 bool DFS(int cur, int tot) {
    10     if(cur==0) {
    11         if(tot>ans) {
    12             ans=tot;
    13             //for(int i=0;i<tot;i++){
    14             //    cout<<cs[i]<<' ';
    15             //}
    16             //cout<<endl;
    17             return 1;
    18         }
    19         return 0;
    20     }
    21     for(int i=0; i<cur; i++) {
    22         if(cur-i+tot<=ans) return 0;
    23         int u=alt[tot][i];
    24         if(mx[u]+tot<=ans) return 0;
    25         int nxt=0;//cs[tot]=u;
    26         for(int j=i+1; j<cur; j++)
    27             if(g[u][alt[tot][j]])
    28                 alt[tot+1][nxt++]=alt[tot][j];
    29         if(DFS(nxt, tot+1)) return 1;
    30     }
    31     return 0;
    32 }
    33 int MaxClique() {
    34     for(int i=cnt;i>=0; i--) {
    35         //cs[0]=i;
    36         int cur=0;
    37         for(int j=i+1; j<=cnt; j++)
    38             if(g[i][j])
    39                 alt[1][cur++]=j;
    40         DFS(cur, 1);
    41         mx[i]=ans;
    42     }
    43     return ans;
    44 }
    45 int main(){
    46     ios::sync_with_stdio(false);
    47     memset(g,1, sizeof(g));
    48     cin>>n>>m;
    49     for(int i=1;i<=n;i++){
    50         cin>>op;
    51         if(op==1) v.clear();
    52         else{
    53             cin>>s;
    54             if(!mp.count(s))mp[s]=++cnt;
    55             int tmp = mp[s];
    56             for(auto q:v)
    57                 g[tmp][q]=g[q][tmp]=false;
    58             v.push_back(tmp);
    59         }
    60     }
    61     cout<<MaxClique()<<endl;
    62 }
    View Code
  • 相关阅读:
    编译环境及编译器介绍
    linux下同步window的firefox
    DPDK pdump抓包说明
    linux TCP协议(1)---连接管理与状态机
    Linux用户态数据发送和接收
    DPDK之内存管理
    linux socket系统调用层
    linux网络栈结构
    DPDK mbuf何时释放回内存池?
    虚拟设备之linux网桥
  • 原文地址:https://www.cnblogs.com/MXang/p/10354144.html
Copyright © 2020-2023  润新知