[图论]二分图
封锁阳光大学
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 }
开始知道这个算法,可是wa,然后思考改善这个算法。
No matter how you feel, get up , dress up , show up ,and never give up.