• 2019-2020 ACM-ICPC Latin American Regional Programming Contest A- Algorithm Teaching 二分图


    #include<bits/stdc++.h>
    #define f first
    #define s second
    using namespace std;
    typedef long long ll;
    const int N=300005; 
    typedef pair<int,int> P;
    int n,tot,t,V;
    map<string,int> mp;
    map<vector<int>,int> mp2;
    vector<int> G[N];
    int match[N];
    bool used[N];
    void add_edge(int u,int v)
    {
    	G[u].push_back(v);
    	G[v].push_back(u);
    }
    int get_id(string str)
    {
    	if(mp.find(str)==mp.end()) 
    		mp[str]=++tot;
    	return mp[str];
    }
    int get_ver_id(vector<int> &v)
    {
    	if(mp2.find(v)==mp2.end()) 
    		mp2[v]=++t;
    	return mp2[v];
    }
    vector<int> v;
    string str;
    bool dfs(int v)
    {
    	used[v]=true;
    	for(int i=0; i<G[v].size(); i++)
    	{
    		int u=G[v][i],w=match[u];
    		if(w<0||!used[w]&&dfs(w))
    		{
    			match[v]=u;
    			match[u]=v;
    			return true;
    		}
    	}
    	return false;
    }
    int matching()
    {
    	int res=0;
    	memset(match,-1,sizeof(match));
    	for(int v=1; v<=V; v++)
    	{
    		if(match[v]<0)
    		{
    			memset(used,0,sizeof(used));
    			if(dfs(v))
    				res++;
    		}
    	}
    	return res;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0; i<n; i++)
    	{
    		int x;
    		scanf("%d",&x);
    		v.clear();
    		for(int j=0; j<x; j++)
    		{
    			cin>>str;
    			v.push_back(get_id(str));
    		}
    		//排序 
    		sort(v.begin(),v.end());
    		for(int mask=1; mask<(1<<x); mask++)
    		{
    			vector<int> tmp;
    			for(int j=0; j<x; j++) 
    				if(mask&(1<<j)) 
    					tmp.push_back(v[j]);
    			get_ver_id(tmp);
    		}
    	}
    	//老师对于每个算法的教的情况 
    	//mp2存每个学生学的算法的状态 
    	int SZ=(int)mp2.size();
    	for(auto p:mp2)
    	{
    		//当前这个学生学的算法 
    		auto x=p.f;
    		//学的算法的数量 
    		int sz=(int)x.size();
    		//学的所有算法的 状态的 编号 
    		int id=get_ver_id(x);
    		//去掉其中一个学过的算法,那么就可以合作了 
    		for(int j=0; j<sz; j++)
    		{
    			vector<int> tmp=x;
    			//去掉其中一个 
    			tmp.erase(tmp.begin()+j); 
    			if(!tmp.size()) 
    				continue; 
    			//建边,也就是这两个点不能合作,因为状态是包含的关系 
    			//拆点建图
    			add_edge(id,SZ+get_ver_id(tmp));
    		}
    	}
    	//要求的是 用最多的不同的路径覆盖所有点
    	//总的 
    	V=2*SZ;
    	printf("%d
    ",SZ-matching());
    	return 0;
    }
    
  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12686496.html
Copyright © 2020-2023  润新知