zoukankan      html  css  js  c++  java
  • 洛谷 1330 封锁阳光大学 图论 二分图染色

    #洛谷 1330 图论 二分图染色

    传送门


    一道比较有个性的图论题目,,需要一点点灵机一动的想法

    好像这是我学过二分图染色之后,第一次单纯的使用它?,,

    观察题目中的河蟹(这是什么梗?),可以发现一个性质,对于每一条街道,其两端的点一定一个放了河蟹,一个没放河蟹,那么显然这是一张二分图,对它进行二分图染色,取点数较小的点集放上河蟹,即为答案.

    注意题目不保证图的连通性,需要对每一块进行该操作并对ans求和

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    const int maxm = 200000 + 500;
    const int maxn = 20000 + 500;
    int last[maxn], pre[maxm], other[maxm];
    int col[maxn];
    int n, m;
    int a, b;
    int tot = 0;
    bool f = 0;
    int sum1 = 0, sum2 = 0;
    int ans = 0;
    
    void add(int x, int y) {
    	tot++;
    	pre[tot] = last[x];
    	last[x] = tot;
    	other[tot] = y;
    }
    
    void dfs(int x, int come) {
    	for (int p = last[x]; p; p = pre[p]) {
    		int q = other[p];
    		if (q == come) continue;
    		if (col[q] == col[x]) {
    			f = 1;
    			return;
    		} else if (col[q] > 0) {
    			continue;
    		} else {
    			if (col[x] == 1) {
    				col[q] = 2;
    				sum2++;
    			} else {
    				col[q] = 1;
    				sum1++;
    			}
    			dfs(q, x);
    		}
    	}
    	
    }
    
    int main () {
    	scanf("%d %d", &n, &m);
    	for (int i = 1; i <= m; i++){
    		scanf("%d %d", &a, &b);
    		add(a, b);
    		add(b, a);
    	}
    	for (int i = 1; i <= n; i++) {
    		if (col[i] == 0) {
    			sum1 = 1;
    			sum2 = 0;
    			col[i] = 1;
    			dfs(i, 0);
    			ans += std :: min(sum1, sum2);
    		}
    	}
    	if (f) printf("Impossible");
    	else printf("%d", ans);
    	return 0;
    }
    
    
  • 相关阅读:
    C# 普印力RFID打印机模板打印
    C# IP地址段端口扫描器封装调用
    W3100SMS 短信猫代码发送 下
    C#动态创建Access数据库,创建加密码Access数据库,更改Access密码
    C# 区分键盘和红外线扫描枪输入 模拟扫描枪
    文件格式大全
    winform获取当前Url地址
    [WPF]使用C#代码实现DataTemplate
    钩子类型
    WM_*
  • 原文地址:https://www.cnblogs.com/CtsNevermore/p/6033618.html
Copyright © 2011-2022 走看看