luogu P1330 封鎖陽光大學 x
阿新 • • 發佈:2017-07-10
printf 不讓 方案 無法 scanf 天都 out log ios
P1330 封鎖陽光大學
題目描述
曹是一只愛刷街的老曹,暑假期間,他每天都歡快地在陽光大學的校園裏刷街。河蟹看到歡快的曹,感到不爽。河蟹決定封鎖陽光大學,不讓曹刷街。
陽光大學的校園是一張由N個點構成的無向圖,N個點之間由M條道路連接。每只河蟹可以對一個點進行封鎖,當某個點被封鎖後,與這個點相連的道路就被封鎖了,曹就無法在與這些道路上刷街了。非常悲劇的一點是,河蟹是一種不和諧的生物,當兩只河蟹封鎖了相鄰的兩個點時,他們會發生沖突。
詢問:最少需要多少只河蟹,可以封鎖所有道路並且不發生沖突。
輸入輸出格式
輸入格式:
第一行:兩個整數N,M
接下來M行:每行兩個整數A,B,表示點A到點B之間有道路相連。
輸出格式:
僅一行:如果河蟹無法封鎖所有道路,則輸出“Impossible”,否則輸出一個整數,表示最少需要多少只河蟹。
輸入輸出樣例
輸入樣例#1:【輸入樣例1】 3 3 1 2 1 3 2 3 【輸入樣例2】 3 2 1 2 2 3輸出樣例#1:
【輸出樣例1】 Impossible 【輸出樣例2】 1
說明
【數據規模】
1<=N<=10000,1<=M<=100000,任意兩點之間最多有一條道路。
思路:
1)黑白染色
2)利用bfs分層搜索的性質,註意要分層!!!
3)如果一個點搜索到一個與自己同色的點,證明不存在合法方案!
4)各個聯通塊分開累加答案!
5)答案就是當前聯通塊內部的黑色與白色的最小值!
坑點:
1)別信數據範圍qwq
2)註意可能存在的好幾個聯通塊的情況!
代碼:
#include <iostream> #include <cstdio> #include <queue> #include <cmath> using namespace std; const int M = 1000010; int n,m,tot,ans; int head[M],a[M],steps[M],w[M],colors[5]; bool QAQ,vis[M]; struct B{ int next,to; }t[M]; void add(int u,int v) { tot++; t[tot].to=v; t[tot].next=head[u]; head[u]=tot; } void bfs(int u) { for(int i=1;i<=n;i++) w[i]=0,steps[i]=0; int fr=0,sz=1; colors[1]=colors[2]=0; steps[1]=1; w[1]=u; a[u]=1; vis[u]=true; while(fr<sz) { fr++; int now=w[fr]; for(int i=head[now];i;i=t[i].next) { int v=t[i].to; if(a[v]==a[now]) { QAQ=false; return; } if(!vis[v]) { vis[v]=true; sz++; w[sz]=v; steps[sz]=steps[fr]+1; if(steps[sz] % 2 == 1) a[v]=1; else if(steps[sz] % 2 == 0) a[v]=2; } } } for(int i=1;i<=sz;i++) colors[a[w[i]]]++; ans+=min(colors[1],colors[2]); } int main() { scanf("%d%d",&n,&m); for(int i=1,a,b;i<=m;i++) { scanf("%d%d",&a,&b); add(a,b),add(b,a); } for(int i=1;i<=n;i++) { if(!vis[i]) { QAQ=true; bfs(i); if(!QAQ) { printf("Impossible\n"); return 0; } } } cout<<ans; return 0; }
luogu P1330 封鎖陽光大學 x