議員祕密 題解

3.議員祕密ios

(secret.pas/c/cpp)ide

 

【問題描述】url

某國有N個議員,大佬XDD要從中選出來一部分一塊兒喝茶談一些事情。某兩個議員之間可能存在矛盾,大佬XDD不但願選出來的這些議員之間有任何矛盾關係,以致於喝喝茶的場面搞得很尷尬。spa

 已知這些議員之間存在M對矛盾關係,你可否幫助大佬XDD計算出他最多能夠選出多少個議員來喝茶談事情?code

若是聰明的你把議員當作點,把矛盾關係當作無向邊,那麼題目中的數據保證M對矛盾所構成的圖中不存在含有超過3個點的環。(圖1符合要求,圖2則不符合)blog

【輸入數據】ip

輸入文件的第一行是用空格隔開的兩個整數N和M,表示一共有N個議員,這些議員之間有M對矛盾關係。接下來的M行,每行將有一對整數a和b(用空格隔開),表示議員a與議員b有矛盾。輸入數據保證不含重邊和自環。(議員的編號都是從1開始的)ci

【輸出數據】get

 輸出一行,包含一個整數,即大佬XDD最多能夠選出多少議員來喝茶談事情。input

【輸入輸出樣例】

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
相關文章
相關標籤/搜索