首先,我們如果把這個圖當做樹來看的話,那麼它有可能不止一棵樹,所以它有可能是森林。我們可以用並查集來維護每乙個連通塊,設 \(root[i]\) 表示連通塊 \(i\) 的根節點是哪乙個,注意,最開始沒有連邊的時候,每乙個連通塊的根都是他自己。
解決完了遍歷的問題後,我們設 \(f[i][0/1]\) 表示在以i為根的子樹上選/不選這個點所需的最少的河蟹數量,則得出轉移方程:
\(f[i][0]=\sum_f[v][1]\)
\(f[i][1]=\sum_f[v][0] +1\)
然後我們將每乙個聯通塊跑一遍樹形 \(dp\),再將答案累加每乙個根放還是不放的最大值,最後輸出答案即可。
最後需要注意的乙個點,如果 \(m\geq n\) 或者遍歷的時候遇到了已經訪問過的點,那麼說明這張圖有迴路,不可能存在合法答案,輸出 \(impossible\)
\(code:\)
#include using namespace std;
struct node
node[200011];
bool book[10011];
int root[10011],f[10011];
int head[10011],tot=0,dp[10011][2];
int n,m;
void init()
int getf(int v)
void merge(int a,int b)
void add(int x,int y)
void dfs(int f,int fa)
book[f]=1;
dp[f][1]=1;
bool flag=0;
for(int i=head[f];i;i=node[i].next) }
int main()
if(m>=n)
cout<<"impossible";
else
printf("%d",ans);
} return 0;
}
P1330 封鎖陽光大學
曹是乙隻愛刷街的老曹,暑假期間,他每天都歡快地在陽光大學的校園裡刷街。河蟹看到歡快的曹,感到不爽。河蟹決定封鎖陽光大學,不讓曹刷街。陽光大學的校園是一張由n個點構成的無向圖,n個點之間由m條道路連線。每只河蟹可以對乙個點進行封鎖,當某個點被封鎖後,與這個點相連的道路就被封鎖了,曹就無法在與這些道路上...
P1330 封鎖陽光大學
曹是乙隻愛刷街的老曹,暑假期間,他每天都歡快地在陽光大學的校園裡刷街。河蟹看到歡快的曹,感到不爽。河蟹決定封鎖陽光大學,不讓曹刷街。陽光大學的校園是一張由n個點構成的無向圖,n個點之間由m條道路連線。每只河蟹可以對乙個點進行封鎖,當某個點被封鎖後,與這個點相連的道路就被封鎖了,曹就無法在與這些道路上...
P1330 封鎖陽光大學
依題意可知,在圖中的每一條邊有且只有乙個點被選中 阻止老曹刷街 那麼就可以對其採取二分圖染色,一條邊中 乙個點為黑色,另乙個點為白色 如果一條邊中的兩個端點的顏色相同,則說明無解,輸出 ipossible 如果有解,就把白點的數目和黑點的數目取 min 即為答案。include include in...