封锁阳光大学

【题目描述】

阳光大学校园是一张由N个点构成的无向图,N个点之间由M条道路连接。每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,人们就无法在这些道路上逛街了。当两只河蟹封锁了相邻的两个点时,他们会发生冲突。

询问最少需要多少只河蟹,可以封锁所有道路并且不发生冲突。

【输入描述】

第一行:两个整数N、M;

接下来M行:每行两个整数A、B,表示点A到点B之间有道路相连。

【输出描述】

输出仅一行,如果河蟹无法封锁所有道路,则输出“Impossible”,否则输出一个整数,表示最少需要多少只河蟹。

【输入样例】

样例1:

3 3

1 2

1 3

2 3

样例2:

3 2

1 2

2 3

【输出样例】

样例1:

Impossible

样例2:

1

【数据范围及提示】

1 <= N <= 10000,1 <= M <= 100000,任意两点之间最多有一条道路。

源代码:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,m,N,M,ans(0),f[10001],i[10001][300];
void DFS(int T) //二分图染色同理。
{
    for (int a=1;a<=i[T][0];a++) //遍历连接。
    {
        if (f[i[T][a]]==f[T]) //父节点重复。
        {
            printf("Impossible");
            exit(0);
        }
          if (!f[i[T][a]]) //没有父节点。
          {
            f[i[T][a]]=3-f[T];
            if (f[i[T][a]]==1)
                N++;
            else
                M++;
            DFS(i[T][a]);
          }
    }
}
int main() //题目数据水,深搜竟AC。
{
    scanf("%d%d",&n,&m);
    for (int a=1;a<=m;a++)
    {
        int t1,t2;
        scanf("%d%d",&t1,&t2);
        i[t1][++i[t1][0]]=t2; //i[t1][0]存储直连边数,同理于下。
        i[t2][++i[t2][0]]=t1; //i[t2][Num]表示t2的第Num条边连接着哪个点。
    }
    for (int a=1;a<=n;a++)
      if (!f[a])
      {
        f[a]=N=1;
        M=0;
        DFS(a);
        ans+=min(N,M);
      }
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Ackermann/p/5806088.html