zoukankan      html  css  js  c++  java
  • P1330 封锁阳光大学(染色问题)

     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,任意两点之间最多有一条道路。

    因为河蟹很不和谐,相邻的点是不能有河蟹的,也就是相邻的点的状态不能相同,这个问题就是染色问题: 
    对于一个点,可以它染成黑色或者白色,所以从第一个可染色的点开始染色,将它染成黑的或者是白的,之后搜索将整张图都染色,统计被染色的黑色总数和白色总数,在两者中取min即是最小放河蟹的数目。 
    注意:1、由于图不一定是联通的,搜索多次。2、M<=100000,开200000,双向建边,QAQ。

     1 #include<cstdio>
     2 #include<queue>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int MAXN = 10100;
     8 struct Edge{
     9     int to,nxt;
    10 }e[200100];    //双向边乘2 
    11 int col[MAXN],head[MAXN];
    12 int n,m,cnt,ans;
    13 queue<int>q;
    14 
    15 void add(int u,int v)
    16 {
    17     ++cnt;
    18     e[cnt].to = v;
    19     e[cnt].nxt = head[u];
    20     head[u] = cnt;
    21 }
    22 
    23 int bfs(int a)
    24 {
    25     int ans1 = 0, ans2 = 0;
    26     col[a] = 1;
    27     ans1++;
    28     q.push(a); 
    29     while (!q.empty())
    30     {
    31         int u = q.front();
    32         q.pop();
    33         for (int i=head[u]; i; i=e[i].nxt)
    34         {
    35             int v = e[i].to;
    36             if (col[v]==0) 
    37             {
    38                 if (col[u]==1) col[v] = 2, ans2++;
    39                 else if (col[u]==2) col[v] = 1, ans1++;
    40                 q.push(v);
    41             }
    42             else if (col[v]==col[u])
    43             {
    44                 printf("Impossible");
    45                 exit(0);
    46             }
    47         }
    48     }
    49     return min(ans1,ans2);
    50 }
    51 
    52 int main()
    53 {
    54     scanf("%d%d",&n,&m);
    55     for (int x,y,i=1; i<=m; ++i)
    56     {
    57         scanf("%d%d",&x,&y);
    58         add(x,y);
    59         add(y,x);
    60     }
    61     for (int i=1; i<=n; ++i)
    62         if (!col[i]) ans += bfs(i);
    63     printf("%d",ans);
    64     return 0;
    65 }

    dfs代码简短一些,注意第29行。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 const int MAXN = 10100;
     6 struct Edge{
     7     int to,nxt;
     8 }e[200100];    //双向边乘2 
     9 int col[MAXN],head[MAXN];
    10 bool vis[MAXN],flag = true; 
    11 int n,m,cnt,ans,ans1,ans2;
    12 
    13 void add(int u,int v)
    14 {
    15     ++cnt;
    16     e[cnt].to = v;
    17     e[cnt].nxt = head[u];
    18     head[u] = cnt;
    19 }
    20 
    21 void dfs(int u,int c)
    22 {
    23     vis[u] = true;
    24     if (c==1) col[u]=2, ans2++;
    25     else if (c==2) col[u] = 1, ans1++;
    26     for (int i=head[u]; i; i=e[i].nxt)
    27     {
    28         int v = e[i].to;
    29         if (vis[v])    //不能写成if(vis[i]&&col[u]==col[v]),影响到else的执行 
    30         {
    31             if (col[v]==col[u])
    32                 flag = false;
    33         }
    34         else dfs(v,col[u]);
    35     }
    36 }
    37 int main()
    38 {
    39     scanf("%d%d",&n,&m);
    40     for (int x,y,i=1; i<=m; ++i)
    41     {
    42         scanf("%d%d",&x,&y);
    43         add(x,y);
    44         add(y,x);
    45     }
    46     for (int i=1; i<=n; ++i)
    47         if (!vis[i])
    48         {
    49             ans1 = ans2 = 0;
    50             dfs(i,1);
    51             if (flag) ans += min(ans1,ans2);
    52             else break;
    53         }
    54     if (flag) printf("%d",ans);
    55     else printf("Impossible");
    56     return 0;
    57 }
  • 相关阅读:
    2020系统综合实践 第3次实践作业
    2020系统综合实践 第2次实践作业
    2020系统综合实践 第1次实践作业
    WireShark组 2019 SDN大作业
    2019 SDN阅读作业
    第07组 Beta版本演示
    OO第四单元总结
    OO第三单元总结
    OO第二单元总结
    OO第一单元总结
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7081853.html
Copyright © 2011-2022 走看看