zoukankan      html  css  js  c++  java
  • Aizu 2306 Rabbit Party DFS

    题目链接:

    http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2306

    题意:

    给定n个点的完全图,下面给出m条边权不为0的边
    下面m行给出边和边权。
    其他的边边权都为0.
    选择一个点集出来,点权是这个点连接这个点集的边权最小值
    找一个这样的子图使得点权和最大,输出点权和。

    题解:

    最后选出来的点,一定是由那m个边所组成的完全图
    因为是一个完全图,所以我们选择的点构成的图一定不包含权值为0的边。因为若包含了权值为0的边,则大可以把这两点删掉而不会减小答案。
    所以我们选择的图中的边一定只 包含给出的m条边,且由这m条边构成的一个团。
    只有100个边,所以最多就是14个点的完全图
    即 n*(n-1)/2 <= 100 => n <=14
    所以爆搜这14个点就可以了

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define MS(a) memset(a,0,sizeof(a))
     5 #define MP make_pair
     6 #define PB push_back
     7 const int INF = 0x3f3f3f3f;
     8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     9 inline ll read(){
    10     ll x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 //////////////////////////////////////////////////////////////////////////
    16 const int maxn = 1e5+10;
    17 
    18 int n,m,mp[105][105],vis[105],ans;
    19 vector<int> Q;
    20 
    21 void dfs(int u){
    22     int tmp = 0;
    23     for(int i=0; i<(int)Q.size(); i++){
    24         int minn = INF;
    25         for(int j=0; j<(int)Q.size(); j++){
    26             if(i!=j) minn = min(minn,mp[Q[i]][Q[j]]);
    27         }
    28         if(minn == INF)
    29             minn = 0;
    30         tmp += minn;
    31     }
    32     ans = max(ans,tmp);
    33 
    34     for(int v=u+1; v<=n; v++){
    35         if(vis[v]) continue;
    36         int flag = 1;
    37         for(int j=0; j<(int)Q.size(); j++){//如果v没有与当前选的点集有权边,v就一定不在要选的点集中
    38             if(mp[v][Q[j]] == 0) {
    39                 flag = 0;
    40                 break;
    41             }
    42         }
    43 
    44         if(flag){
    45             vis[v] = 1;  // 选v
    46             Q.push_back(v);
    47             dfs(v);
    48             vis[v] = 0; // 不选v  因为 选v可能使得答案变小
    49             Q.pop_back();
    50         }
    51     }
    52 }
    53 
    54 int main(){
    55     n=read(), m=read();
    56     for(int i=0; i<m; i++){
    57         int u,v,w; scanf("%d%d%d",&u,&v,&w);
    58         mp[u][v]=mp[v][u]=w;
    59     }
    60 
    61     for(int i=1; i<=n; i++){
    62         vis[i] = 1;
    63         Q.push_back(i); // 枚举肯定选哪个点的情况
    64         dfs(0);
    65         Q.pop_back();
    66         vis[i] = 0;
    67     }
    68 
    69     cout << ans << endl;
    70 
    71     return 0;
    72 }
  • 相关阅读:
    专业英语阅读(二)
    专业英语阅读(一)
    高精度运算
    高精度运算——加减乘除阶乘
    python常见编程面试题汇总
    python线程
    反射
    单例模式
    生成器、迭代器
    python装饰器
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827669.html
Copyright © 2011-2022 走看看