zoukankan      html  css  js  c++  java
  • UVa11419 SAM I AM(构造最小点覆盖)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27475

    【思路】

      二分图的最小点覆盖以及构造最小覆盖。

      二分图的最小点覆盖即在二分图中选出最少的点使能够将所有的边覆盖。构造思路是从所有未盖点出发拓展匈牙利树,X中的未标记点与Y中的已标记点为最小覆盖集。

      具体可见:http://www.tuicool.com/articles/jmAnEb

    【代码】

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    const int maxn =  1000+10;
    
    bool S[maxn],T[maxn];
    int lky[maxn],lkx[maxn];
    vector<int> G[maxn];
    
    bool match(int u) {
    	S[u]=1;
    	for(int i=0;i<G[u].size();i++) {
    		int v=G[u][i];
    		if(!T[v]) {
    			T[v]=1;
    			if(!lky[v] || match(lky[v])) {
    				lky[v]=u , lkx[u]=v;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    int n,m,k;
    
    void read(int& x) {
    	char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	x=0;
    	while(isdigit(c)) {
    		x=x*10+c-'0' , c=getchar();
    	}
    }
    
    int main() {
    	while(scanf("%d%d%d",&n,&m,&k)==3 &&(n)) {
    		for(int i=1;i<=n;i++) G[i].clear();
    		int u,v;
    		for(int i=0;i<k;i++) {
    			read(u),read(v);
    			G[u].push_back(v);
    		}
    		memset(lky,0,sizeof(lky));
    		memset(lkx,0,sizeof(lkx));
    		int ans=0;
    		for(int i=1;i<=n;i++) {
    			memset(T,0,sizeof(T));
    			memset(S,0,sizeof(S));
    			if(match(i)) ans++;
    		}
    		printf("%d ",ans);
    		memset(S,0,sizeof(S));
    		memset(T,0,sizeof(T));
    		for(int i=1;i<=n;i++)
    			if(!lkx[i])  match(i);
    		for(int i=1;i<=n;i++)
    			if(!S[i]) printf("r%d ",i);
    		for(int i=1;i<=n;i++)
    			if(T[i]) printf("c%d ",i);
    		putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    ARC管理内存(一)
    懒加载lazyload
    View的封装
    Plist文件与数据解析
    ubuntu16.04 安装python3.6
    ubuntu16.04 安装 wxPython方法
    第三章
    第二章
    协方差的意义
    内存区--Java
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5077066.html
Copyright © 2011-2022 走看看