1. 程式人生 > >C++ P1330 封鎖陽光大學

C++ P1330 封鎖陽光大學

題目描述

曹是一隻愛刷街的老曹,暑假期間,他每天都歡快地在陽光大學的校園裡刷街。河蟹看到歡快的曹,感到不爽。河蟹決定封鎖陽光大學,不讓曹刷街。

陽光大學的校園是一張由N個點構成的無向圖,N個點之間由M條道路連線。每隻河蟹可以對一個點進行封鎖,當某個點被封鎖後,與這個點相連的道路就被封鎖了,曹就無法在與這些道路上刷街了。非常悲劇的一點是,河蟹是一種不和諧的生物,當兩隻河蟹封鎖了相鄰的兩個點時,他們會發生衝突。

詢問:最少需要多少隻河蟹,可以封鎖所有道路並且不發生衝突。

輸入輸出格式

輸入格式:

第一行:兩個整數N,M

接下來M行:每行兩個整數A,B,表示點A到點B之間有道路相連。

輸出格式:

僅一行:如果河蟹無法封鎖所有道路,則輸出“Impossible”,否則輸出一個整數,表示最少需要多少隻河蟹。

輸入輸出樣例

輸入樣例1:

3 3
1 2
1 3
2 3

輸出樣例1:

Impossible

輸入樣例2:

3 2
1 2
2 3

輸出樣例2:

1

說明

【資料規模】

1<=N<=10000,1<=M<=100000,任意兩點之間最多有一條道路。

題目連結:https://www.luogu.org/problemnew/show/P1330 


個人思路:

  • 首先,將存在河蟹的點視為被染色的點,就可以考慮到二分圖染色.
  • 由於資料不保證此圖為聯通圖,需要遍歷所有點進行BFS,當然也需要vis陣列儲存某個點是否被訪問過的資料.
  • 在每一個聯通子圖的BFS過程中,取較小的一個進行返回即可(因為只要二分圖中一半的點被染色,該題題意即符合).
  • 最終,對所有聯通子圖的BFS結果進行求和即可.

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=10005,M=200005;
int n,m,cnt=0,head[N],cl[N],vis[N],ansA=0;
struct Edge{
    int v,w,nxt;
}e[M];
void addEdge(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
int ans[2]{0,0};
int bfs(int x){
    queue<int> q;
    q.push(x);
    while(!q.empty()){
        int nowValue=q.front();q.pop();
        for(int i=head[nowValue];i;i=e[i].nxt){
            int nowV=e[i].v;
            if(cl[nowV]==-1){
                cl[nowV]=cl[nowValue]^1;
                ans[cl[nowV]]++;
                q.push(nowV);
            }
            if(cl[nowV]==cl[nowValue]){
                return -1;
            }
        }
    }
    return min(ans[0],ans[1]);
}
int main(){
    memset(cl,-1,sizeof(cl));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int ta,tb;
        scanf("%d%d",&ta,&tb);
        addEdge(ta,tb,1);
        addEdge(tb,ta,1);
    }
    for(int i=1;i<=n;i++){
        if(cl[i]==-1){
            cl[i]=1;
            ans[1]++;
            //cout<<"bfs:"<<i<<endl;
            int tempAns=bfs(i);
            if(tempAns==-1){
                printf("Impossible\n");
                return 0;
            }
            ansA+=tempAns;
            memset(ans,0,sizeof(ans));
        }
    }
    printf("%d\n",ansA);
    return 0;
}