zoukankan      html  css  js  c++  java
  • BZOJ 1143: [CTSC2008]祭祀river 最大独立集

    题目链接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1143

    题解:

    给你一个DAG,求最大的顶点集,使得任意两个顶点之间不可达。

    把每个顶点v拆成v和v',对于边u,v,建成(u,v'),得到一个二分图。

    先对二分图floyd求闭包,然后求二分图的最大独立集就可以了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    const int maxn = 111;
    
    int mat[maxn][maxn];
    int vis[maxn], lef[maxn];
    int n, m;
    
    void init() {
    	memset(mat, 0, sizeof(mat));
    	memset(lef, 0, sizeof(lef));
    }
    
    bool match(int u) {
    	for (int i = 1; i <= n; i++) {
    		if (mat[u][i]&&!vis[i]) {
    			vis[i] = 1;
    			if (!lef[i] || match(lef[i])) {
    				lef[i] = u;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    int main() {
    	while (scanf("%d%d", &n, &m) == 2 && n) {
    		init();
    		for (int i = 0; i < m; i++) {
    			int u, v;
    			scanf("%d%d", &u, &v);
    			mat[u][v] = 1;
    		}
    		for (int k = 1; k <= n; k++) {
    			for (int i = 1; i <= n; i++) {
    				for (int j = 1; j <= n; j++) {
    					if (mat[i][k] && mat[k][j]) {
    						mat[i][j] = 1;
    					}
    				}
    			}
    		}
    		for (int i = 1; i <= n; i++) {
    			memset(vis, 0, sizeof(vis));
    			match(i);
    		}
    		int cnt = 0;
    		for (int i = 1; i <= n; i++) {
    			if (lef[i] != 0) cnt++;
    		}
    		printf("%d
    ", n - cnt);
    	}
    	return 0;
    }
    
  • 相关阅读:
    zabbix迁移思路
    top命令
    random随机数
    判断传入元素是否可见
    title_contains
    1.Selenium的工作原理以及网页上查找元素
    APP升级测试
    英语词汇
    作文 |素材笔记
    408计组 |二、数据的表示和运算
  • 原文地址:https://www.cnblogs.com/fenice/p/5597251.html
Copyright © 2011-2022 走看看