• poj1325机器工作——二分图最小点覆盖


    题目:http://poj.org/problem?id=1325

    二分图求最大匹配,即为最小点覆盖;

    一开始我写得较麻烦,求出最大匹配又去搜增广路,打标记求最小点覆盖;

    然而两种方法都没写“ans=0”,WA了好几次,心力交瘁时才发现,改后即A,心力交瘁。

    代码1如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m,k,pre1[305],pre2[305],head[305],ct,ans;
    bool vis[305];
    struct N{
    	int to,next;
    }edge[3005];
    void add(int x,int y)
    {
    	ct++;
    	edge[ct].to=y;
    	edge[ct].next=head[x];
    	head[x]=ct;
    }
    bool dfs(int b)
    {
    	for(int i=head[b];i;i=edge[i].next)
    	{
    		int a=edge[i].to;
    		if(vis[a])continue;
    		vis[a]=1;
    		if(!pre1[a]||dfs(pre1[a]))
    		{
    			pre1[a]=b;
    			pre2[b]=a;
    			return 1;
    		}
    	}
    	return 0;
    }
    bool dfs2(int b)
    {
    	vis[b]=1;
    	for(int i=head[b];i;i=edge[i].next)
    	{
    		int a=edge[i].to;
    		if(vis[a])continue;
    		vis[a]=1;
    		if(!pre1[a]||dfs2(pre1[a]))
    		{
    			pre1[a]=b;
    			pre2[b]=a;
    			return 1;
    		}
    	}
    	return 0;
    }
    int main()
    {
    	while(1)
    	{
    		ct=0;ans=0;//!
    		memset(pre1,0,sizeof pre1);
    		memset(pre2,0,sizeof pre2);
    		memset(head,0,sizeof head);
    		scanf("%d",&n);
    		if(!n)return 0;
    		scanf("%d%d",&m,&k);
    		int d,a,b;
    		for(int i=1;i<=k;i++)
    		{
    			scanf("%d%d%d",&d,&a,&b);
    			if(a*b==0)continue;
    			add(a+100,b);
    			add(b,a+100);
    		}
    		for(int i=1;i<m;i++)//最大匹配 
    			if(!pre2[i])
    			{
    				memset(vis,0,sizeof vis);
    				vis[i]=1;//
    				dfs(i);
    			}
    		memset(vis,0,sizeof vis);
    		for(int i=1;i<m;i++)
    			if(!pre2[i])
    				dfs2(i);
    		for(int i=1;i<m;i++)
    			if(!vis[i])ans++;
    		for(int i=101;i<n+100;i++)
    			if(vis[i])ans++;
    		printf("%d
    ",ans);
    	}
    }
    

    代码2如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m,k,pre[305],head[305],ct,ans;
    bool vis[305];
    struct N{
    	int to,next;
    }edge[3005];
    void add(int x,int y)
    {
    	ct++;
    	edge[ct].to=y;
    	edge[ct].next=head[x];
    	head[x]=ct;
    }
    bool dfs(int b)
    {
    	vis[b]=1;
    	for(int i=head[b];i;i=edge[i].next)
    	{
    		int a=edge[i].to;
    		if(vis[a])continue;
    		vis[a]=1;
    		if(!pre[a]||dfs(pre[a]))
    		{
    			pre[a]=b;
    			pre[b]=a;
    			return 1;
    		}
    	}
    	return 0;
    }
    
    int main()
    {
    	while(1)
    	{
    		ct=0;ans=0;//
    		memset(pre,0,sizeof pre);
    		memset(head,0,sizeof head);
    		scanf("%d",&n);
    		if(!n)return 0;
    		scanf("%d%d",&m,&k);
    		int d,a,b;
    		for(int i=1;i<=k;i++)
    		{
    			scanf("%d%d%d",&d,&a,&b);
    			if(a*b==0)continue;
    			add(a+100,b);
    			add(b,a+100);
    		}
    		for(int i=1;i<m;i++)//最大匹配 
    			if(!pre[i])
    			{
    				memset(vis,0,sizeof vis);
    				if(dfs(i))ans++;
    			}
    		printf("%d
    ",ans);
    	}
    }
    

      

  • 相关阅读:
    学习Hadoop不错的系列文章(转)
    浏览器的渲染原理简介
    大数据人才缺乏,你准备好了吗?
    SVN分支与合并透析
    Windows下SVN服务端(Subversion)及客户端(TortoiseSVN)详细安装教程
    maven2介绍(转)
    eclipse安装velocity插件(转)
    为大数据时代做好准备——来自《大数据的冲击》一书精彩片段(转)
    【VB】Format 格式化日期时间数字函数详解
    获取本机ID和电脑名称
  • 原文地址:https://www.cnblogs.com/Zinn/p/8463679.html
Copyright © 2020-2023  润新知