[图论]二分图

封锁阳光大学

Description

曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街。河蟹看到欢快的曹,感到不爽。河蟹决定封锁阳光大学,不让曹刷街。

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

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

 

Input

第一行:两个整数N,M

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

Output

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

Examples

Input

3 3
1 2
1 3
2 3

Output

Impossible

 

Input

3 2
1 2
2 3

Output

1

 

正确解法:

刚开始想到了是二分图,然后wa了,我发现有cor为0的点,看了看题解。发现这可能不是一张图。

会有好几个连接分块

找完分块之后,发现又wa了。

我知道找 1和2 中最小的那个 ,但是应该是每个分块中最小的加起来。

要不然光找为1的,可能这个分块中1小,另一个分块中2小。

就不成立了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<map>
 6 #include<set>
 7 #include<vector>
 8 #include<queue>
 9 #include<algorithm>
10 #include<cmath>
11 using namespace std;
12 typedef long long ll;
13 const int N=100000+10;
14 const int M=1000000+100;
15 int cor[N],Link[N],bok[N],len=0,que[M];
16 int n,m,xx,yy,ans=0;
17 struct student
18 {
19     int y,next;
20 }e[M];
21 void insert(int xx,int yy)
22 {
23     e[++len].next=Link[xx];
24     Link[xx]=len;
25     e[len].y=yy;
26 }
27 void init()
28 {
29     scanf("%d %d",&n,&m);
30     while(m--)
31     {
32         scanf("%d %d",&xx,&yy);
33         insert(xx,yy);
34         insert(yy,xx);
35     }
36 }
37 int bfs(int x)
38 {
39     int head=1,tail=2;
40     int aa=1,bb=0;
41     que[1]=x;
42     bok[x]=1;
43     cor[x]=1;
44     while(head<tail)
45     {
46         for(int i=Link[que[head]];i;i=e[i].next)
47         {
48             int tt=que[head];
49             if(!cor[e[i].y])
50             {
51                 if(cor[tt]==1)
52                 {    cor[e[i].y]=2;
53                     bb++;
54                 }
55                 else if(cor[tt]==2)
56                 {    cor[e[i].y]=1;
57                     aa++;
58                 }
59             }
60             else if(cor[tt]==cor[e[i].y])
61                 return 0;
62             if(!bok[e[i].y])
63             {
64                 bok[e[i].y]=1;
65                 que[tail++]=e[i].y;
66             }
67         }
68         head++;
69     }
70     ans+=min(aa,bb);
71     return 1;
72 }
73 int main()
74 {
75     init();
76     for(int i=1;i<=n;i++)
77         if(!bok[i])
78         {
79             if(!bfs(i))
80             {
81                 printf("Impossible\n");
82                 return 0;
83             }
84         }
85     printf("%d\n",ans);
86 
87     return 0;
88 }
View Code

开始知道这个算法,可是wa,然后思考改善这个算法。

 

posted @ 2019-03-02 14:57  kaike  阅读(186)  评论(0编辑  收藏  举报