【UOJ 347】LazyChild黑OJ
阿新 • • 發佈:2020-11-26
【題目描述】:
LazyChild開了一家“善良OJ”。但大多數人都不知道,這其實是家黑OJ。親愛的同學,請不要驚訝,古時候有黑店,現代為什麼不能有黑OJ呢?每AC一道題,網站便會自動在電腦上安裝一種木馬。LazyChild通過竊取資訊獲取收益(如網遊帳號、OI資料、YuanY和TT的照片等等)。
作為一名資深黑客,老Z某日突然發現,“善良OJ”上的木馬,自己電腦上都沒有。這可十分讓他過意不去。老Z決定通過多A題,來豐富自己電腦的病毒庫。
經過調查,老Z發現,很多木馬是不能共存的。比如“和諧”木馬與“團結”木馬,兩者只能任選其一。然而,老Z是個完美主義者,他想要自己的病毒庫儘可能充實。
老Z不懈的追求最終感動了上天。天上的神仙(半仙?)“牛人雨”給這個問題稍稍降低了一點難度。神仙規定,對於n種木馬,有且僅有(n-1)對不能共存,並且對於每種木馬,都存在至少一個木馬與之不能共存。
老Z不在乎自己AC多少題。請告訴他,他最多能從“善良OJ”上獲取木馬的個數。
【輸入描述】:
第一行,一個正整數n,表示木馬個數。
剩餘(n-1)行,每行一對木馬,表示他們不能共存。(保證相同的木馬可以共存,任意不同兩行的描述不等價)
木馬編號從0至(n-1)
【輸出描述】:
一行,老Z最多獲得木馬的個數。你可以認為開始時沒有任何木馬。
【樣例輸入】:
3
0 1
1 2
【樣例輸出】:
2
【時間限制、資料範圍及描述】:
時間:1s 空間:256M
對於100%的資料,1<=n<=200
- Universal Online Judge
Server time: 2020-11-26 19:22:13 | 開源專案
題解:20%算是貪心?就是把分成兩個陣營√敵人的敵人就是我的朋友
void dfs(int now,int jjj){ //printf("%d\n",now); if(jjj==1){ ans1++; //vis[now]=1; for(int i=head[now];i;i=e[i].next) if(vis[e[i].to]==0) { vis[e[i].to]=1; dfs(e[i].to,2); } } if(jjj==2){ ans2++; //vis[now]=1; for(int i=head[now];i;i=e[i].next) if(vis[e[i].to]==0) { vis[e[i].to]=1; dfs(e[i].to,1); } } return; }
100%樹形DP 類似於沒有上司的舞會
#include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<bits/stdc++.h> typedef long long ll; using namespace std; const int N=202; int n,x,y,vis[N],dp[N][3]; int head[N],cnt,b[N][N],f[N][N]; struct node{ int to; int next; }e[N*4]; void add(int u,int v){ e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } int ans1,ans2; void dfs(int now,int jjj){ //printf("%d\n",now); if(jjj==1){ ans1++; //vis[now]=1; for(int i=head[now];i;i=e[i].next) if(vis[e[i].to]==0) { vis[e[i].to]=1; dfs(e[i].to,2); } } if(jjj==2){ ans2++; //vis[now]=1; for(int i=head[now];i;i=e[i].next) if(vis[e[i].to]==0) { vis[e[i].to]=1; dfs(e[i].to,1); } } return; } void work(){ /*for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) continue; if(b[i][j]==1){ f[i][0]=max(f[i][0],max(f[j][1],f[j][0])); f[i][1]=max(f[i][1],f[j][0])+1; } if(b[i][j]==0){ f[i][0]=max(f[i][0],max(f[j][1],f[j][0])); f[i][1]=max(f[i][0],max(f[j][1],f[j][0]))+1; } } } printf("%d",max(f[n][0],f[n][1]));*/ for(int xx=0;xx<n;xx++){ for(int i=head[xx];i;i=e[i].next){ int v=e[i].to; dp[xx][1]+=dp[v][0]; dp[xx][0]+=max(dp[v][0],dp[v][1]); } dp[xx][1]++; } cout<<max(dp[n-1][0],dp[n-1][1]); } void dfss(int u,int fa){ dp[u][1]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa) continue; dfss(v,u); dp[u][1]+=dp[v][0]; dp[u][0]+=max(dp[v][0],dp[v][1]); } } int main(){ freopen("blackoj.in","r",stdin); freopen("blackoj.out","w",stdout); scanf("%d",&n); for(int i=1;i<n;i++){ scanf("%d %d",&x,&y); b[x][y]=b[y][x]=1; add(x+1,y+1); add(y+1,x+1); } dfss(1,0); printf("%d\n",max(dp[1][0],dp[1][1])); //work(); //vis[0]=1; dfs(0,1); // cout<<max(ans1,ans2); //printf("%d %d",ans1,ans2); return 0; }