zoukankan      html  css  js  c++  java
  • 议员秘密 题解

    3.议员秘密

    (secret.pas/c/cpp)

    【问题描述】

    某国有N个议员,大佬XDD要从中选出来一部分一起喝茶谈一些事情。某两个议员之间可能存在矛盾,大佬XDD不希望选出来的这些议员之间有任何矛盾关系,以至于喝喝茶的场面搞得很尴尬。

     已知这些议员之间存在M对矛盾关系,你能否帮助大佬XDD计算出他最多可以选出多少个议员来喝茶谈事情?

    如果聪明的你把议员看成点,把矛盾关系看成无向边,那么题目中的数据保证M对矛盾所构成的图中不存在含有超过3个点的环。(图1符合要求,图2则不符合)

    【输入数据】

    输入文件的第一行是用空格隔开的两个整数N和M,表示一共有N个议员,这些议员之间有M对矛盾关系。接下来的M行,每行将有一对整数a和b(用空格隔开),表示议员a与议员b有矛盾。输入数据保证不含重边和自环。(议员的编号都是从1开始的)

    【输出数据】

     输出一行,包含一个整数,即大佬XDD最多可以选出多少议员来喝茶谈事情。

    【输入输出样例】

    secret.in

    5 6

    1 2

    3 2

    1 3

    3 5

    3 4

    4 5

    secret.out

    2

    【样例说明】

    某国有6个议员,矛盾关系中1 - 2 - 3组成一个环,3 - 4 - 5组成一个环,因此只能在这两个环中分别选一个议员,并且不能选择3号议员。

    【数据规模与约定】

    对于20%的数据,1 ≤ N ≤ 20

    对于40%的数据,1 ≤ N ≤ 50

    对于100%的数据,1 ≤ N ≤ 200

    输入数据保证合法。

    ————————————————————我是分割线————————————————————————

    dp题目。据说是树状(仙人掌???)。

    dp[i][j]表示第i个点,选(j==1)或不选(j==0)的情况。

    注意题目没有保证联通,有可能是森林。

    写的记忆化搜索,代码如下:

     1 /*
     2     Problem:
     3     OJ:
     4     User:    S.B.S.
     5     Time:
     6     Memory:
     7     Length:
     8 */
     9 #include<iostream>
    10 #include<cstdio>
    11 #include<cstring>
    12 #include<cmath>
    13 #include<algorithm>
    14 #include<queue>
    15 #include<cstdlib>
    16 #include<iomanip>
    17 #include<cassert>
    18 #include<climits>
    19 #include<functional>
    20 #include<bitset>
    21 #include<vector>
    22 #include<list>
    23 #define F(i,j,k) for(register int i=j;i<=k;++i)
    24 #define M(a,b) memset(a,b,sizeof(a))
    25 #define FF(i,j,k) for(register int i=j;i>=k;i--)
    26 #define maxn 210
    27 #define inf 0x3f3f3f3f
    28 #define maxm 4001
    29 #define mod 998244353
    30 #define LOCAL
    31 using namespace std;
    32 int read(){
    33     int x=0,f=1;char ch=getchar();
    34     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    35     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    36     return x*f;
    37 }
    38 int n,m;
    39 int fa[maxn],dp[maxn][2];
    40 bool tree[maxn][maxn];
    41 bool vis[maxn],mp[maxn][maxn];
    42 inline void dfs(int u)
    43 {
    44     vis[u]=true;
    45     F(i,1,n){
    46         if(!vis[i]&&mp[u][i]){
    47             tree[u][i]=1;
    48             fa[i]=u;
    49             dfs(i);
    50         }
    51     }
    52 }
    53 inline int solve(int u,int v)
    54 {
    55     int cnt;
    56     if(dp[v][u]!=-1) return dp[v][u];
    57     if(u==0){
    58         cnt=0;
    59         F(i,1,n) if(tree[v][i]) cnt+=max(solve(0,i),solve(1,i));
    60         return dp[v][u]=cnt;
    61     }
    62     else{
    63         bool temp[maxn];M(temp,0);
    64         F(i,1,n){
    65             if(tree[v][i]){
    66                 temp[i]=true;
    67                 F(j,1,n) if(tree[i][j]&&mp[v][j]) temp[j]=true;
    68             }
    69         }
    70         cnt=0;
    71         F(i,1,n) if(!temp[i]&&fa[i]!=-1&&temp[fa[i]])
    72             cnt+=max(solve(0,i),solve(1,i));
    73         return dp[v][u]=cnt+1;
    74     }
    75 }
    76 int ans;
    77 int main()
    78 {
    79     std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y;
    80     #ifdef LOCAL
    81     freopen("input.txt","r",stdin);
    82     freopen("output.txt","w",stdout);
    83     #endif
    84     cin>>n>>m;
    85     M(dp,-1);M(fa,-1);
    86     F(i,1,m){int a,b;cin>>a>>b;mp[a][b]=mp[b][a]=1;}
    87     F(i,1,n){
    88         if(!vis[i]){
    89             dfs(i);
    90             ans+=max(solve(0,i),solve(1,i));
    91         }
    92     }
    93     cout<<ans<<endl;
    94     return 0;
    95 }
    3
  • 相关阅读:
    no route to host
    修改文件失败,提示E509: 无法创建备份文件 (请加 ! 强制执行)
    OAuth2.0的四种授权模式
    Django--JWT认证
    Django--数据库ORM操作
    DRF中限流、过滤、排序、分页
    Django框架中序列化与反序列化与字段验证
    21.Django三种风格的模型继承
    20.第三方微博登录Django+Vue
    博客园图片点击放大功能
  • 原文地址:https://www.cnblogs.com/SBSOI/p/6057938.html
Copyright © 2011-2022 走看看