惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
Forbes - Security
Forbes - Security
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
S
Securelist
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
P
Proofpoint News Feed
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
AWS News Blog
AWS News Blog
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
Last Week in AI
Last Week in AI
Engineering at Meta
Engineering at Meta
Spread Privacy
Spread Privacy
博客园_首页
T
Tor Project blog
The Cloudflare Blog
博客园 - 聂微东
罗磊的独立博客
Cyberwarzone
Cyberwarzone
腾讯CDC
T
The Exploit Database - CXSecurity.com
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Privacy International News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
U
Unit 42
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
A
About on SuperTechFans
G
GRAHAM CLULEY
K
Kaspersky official blog
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
T
Tenable Blog
L
LINUX DO - 最新话题
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
TaoSecurity Blog
TaoSecurity Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
MongoDB | Blog
MongoDB | Blog
T
The Blog of Author Tim Ferriss
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 司徒正美
O
OpenAI News
Recent Announcements
Recent Announcements

博客园 - zealsoft

洛谷 P1816 忠诚题解 洛谷 P2384 最短路题解 洛谷 P2725 邮票题解 洛谷 P2722 总分题解 洛谷 P1219 八皇后题解 洛谷 P2921 在农场万圣节Trick or Treat on the Farm题解 洛谷 P1162 填涂颜色题解 洛谷 P1032 字串变换题解 洛谷 P1443 马的遍历题解 洛谷 P1280 尼克的任务题解 洛谷 P1020导弹拦截题解 洛谷 P1141 01迷宫题解 VisualSVNServer无法卸载也无法安装,报告不是有效的MOF文件(0x8004401e)错误 视频捕捉的格式问题 一个VxWorks源代码网站 找个轻量级的Log库还挺难 TAU G2中的BitString和OctetString W32.Downadup.autorun病毒的清除 如何用Visual Studio 2005编译Wireshark的插件
洛谷 P1330 封锁阳光大学题解
zealsoft · 2019-08-23 · via 博客园 - zealsoft

题目描述

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

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

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

输入格式

第一行:两个整数N,M

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

输出格式

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

输入输出样例

说明/提示

【数据规模】

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


题解

本题实际上是一道二分图的题目。

如果我们把图中U、V两个集合中的所有连线都用河蟹断开,就达到了题目要求。要判断图中的二分图,只需要类似01迷宫进行BFS遍历染色即可。在染色的过程中,如果发现连线的另一个端点未染色,就用和当前端点不同的颜色染色,要是已经染色且和当前节点颜色相同,就说明构成循环圈,不能构成二分图,类似下图的情况。

代码如下:

  1 #include <iostream>
  2 #include <math.h>
  3 #include <stdio.h>
  4 #include <algorithm>
  5 #include <string.h>
  6 
  7 using namespace std;
  8 
  9 const int MAXN = 100005;
 10 int first[MAXN], n, m, en, color[MAXN], f[2], u, v; //f统计不同颜色节点数 
 11 int front, rear; 
 12 bool vis[MAXN]; 
 13 int ans;
 14 
 15 struct edge
 16 {
 17     int zhongdian, changdu;
 18     int next;
 19 };
 20 
 21 edge ed[MAXN]; 
 22 
 23 void add_edge(int s, int e, int d) 
 24 {
 25     en++; 
 26     ed[en].next = first[s]; 
 27     first[s] = en;
 28     ed[en].zhongdian = e;
 29     ed[en].changdu = d;
 30 }
 31 
 32 struct Node
 33 {
 34     int x, y;
 35     int step;
 36 };
 37 Node q[MAXN];
 38 
 39 int bfs(int a)
 40 {
 41     Node now, next;
 42     now.x = a;
 43     vis[a] = 1;
 44     color[a] = 1;
 45     f[0] = 0;
 46     f[1] = 1;
 47     front = rear = 0;
 48     q[rear] = now;
 49     rear++;
 50     while(front < rear)
 51     {
 52         now = q[front++];
 53         for(int i = first[now.x]; i; i = ed[i].next)
 54         //first[now]:当前点的第一条边;ed[i].next:下一个访问的点  
 55         {
 56             if(color[ed[i].zhongdian] != -1)
 57             {
 58                 if(color[ed[i].zhongdian] == color[now.x])
 59                 {
 60                     cout << "Impossible" << endl;
 61                     return -1;
 62                 }
 63             } 
 64             else
 65             {
 66                 color[ed[i].zhongdian] = (color[now.x] + 1) % 2;
 67                 q[rear].x = ed[i].zhongdian;
 68                 rear++;
 69                 f[color[ed[i].zhongdian]]++;
 70             }
 71         } 
 72     }
 73     ans += min(f[0], f[1]);
 74 }
 75 
 76 int main()
 77 {
 78     cin >> n >> m;
 79     for(int i = 1; i <= n; i++)
 80     {
 81         color[i] = -1; //初始化  
 82     }
 83     for(int i = 1; i <= m; i++)
 84     {
 85         cin >> u >> v;
 86         add_edge(u, v, 0);
 87         add_edge(v, u, 0);
 88     }
 89     for(int i = 1; i <= n; i++)
 90     {
 91         if(color[i] == -1)
 92         {
 93             if(bfs(i) < 0)
 94             {
 95                 return 0;
 96             }
 97         } 
 98     }
 99     cout << ans << endl;
100     
101     return 0;
102 }

代码中的f数组是用来统计黑白两种染色点的个数的,本题所求的最小河蟹数就是两种染色点个数的最小值。