• 蓝书二分图例题


    CH6801 棋盘覆盖

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e4+10,M=210;
    
    int head[N],nxt[N*2],to[N*2],a[M][M],vis[N],match[N];
    int num,m,n,ans;
    
    void add(int x,int y)
    {
    	nxt[++num]=head[x],to[num]=y,head[x]=num;
    }
    
    bool dfs(int x)
    {
    	for(int i=head[x],y; i ;i=nxt[i])
    		if(!vis[y=to[i]])
    		{
    			vis[y]=1;//一开始写在外面,错了; 
    			if(!match[y] || dfs(match[y]))
    			{
    				match[x]=y; match[y]=x;// 一开始没写第二句,错了; 
    				return true ;
    			}
    		}
    	return false ;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y; scanf("%d%d",&x,&y);
    		a[x][y]=1;
    	}
    	
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    		{
    			if(a[i][j]==1) continue ;
    			int x=i*n+j-n;
    			
    			if(j<n && !a[i][j+1]) add(x,x+1);
    			if(j>1 && !a[i][j-1]) add(x,x-1);
    			
    			if(i<n && !a[i+1][j]) add(x,x+n);
    			if(i>1 && !a[i-1][j]) add(x,x-n);
    		}
    	
    	for(int i=1;i<=n*n;i++)
    		if(!match[i])
    		{
    			memset(vis,0,sizeof(vis));
    			if(dfs(i)) ans++;
    		}
    		
    	cout<<ans<<endl; 
    	return 0;	
    }
    

    CH6802 车的放置

    #include<bits/stdc++.h>
    using namespace std;
    const int N=210,M=1e3+10;
    
    int head[M],to[M],nxt[M],a[N][N],match[M],vis[M];
    int n,m,t,num,ans;
    
    int read()
    {
    	int x; scanf("%d",&x);
    	return x;
    }
    
    void add(int x,int y)
    {
    	nxt[++num]=head[x],to[num]=y,head[x]=num;
    }
    
    bool dfs(int x)
    {
    	for(int i=head[x],y; i ;i=nxt[i])
    		if(!vis[y=to[i]])
    		{
    			vis[y]=1;
    			if(!match[y] || dfs(match[y]))
    			{
    				match[y]=x,match[x]=y;
    				return true ;
    			}
    		}
    	return false ;
    }
    
    int main()
    {
    	n=read(),m=read(),t=read();
    	for(int i=1;i<=t;i++)
    	{
    		int x=read(),y=read();
    		a[x][y]=1;
    	}
    	
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			if(!a[i][j])
    				add(i,n+j),add(n+j,i);
    				
    	for(int i=1;i<=n;i++)
    		if(!match[i])
    		{
    			memset(vis,0,sizeof(vis));
    			if(dfs(i)) ans++;
    		}
    	
    	cout<<ans<<endl;
    	return 0;
    }
    

    CH6803导弹防御塔

    坑人题。T1单位给的是秒,T2单位给的是分钟。坑了我两个小时。
    emmm试了一下用vector代替链式前向星,挺爽的。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=100,M=5e3;
    const double EPS=1e-8;
    
    vector<int> G[N];
    int tx[N],ty[N],mx[N],my[N],id[M];
    int match[M],vis[M];
    int n,m,num,tot;
    double T1,T2,V,tme[M];
    
    int read()
    {
        int x; scanf("%d",&x);
        return x;
    }
    
    double dis(int i,int j)
    {
        double x=tx[i]-mx[j],y=ty[i]-my[j];
        return sqrt(x*x+y*y);
    }
    
    void init(double mid)
    {
        memset(match,0,sizeof(match));
    	for(int i=1;i<=m;i++) G[i].clear();
    	for(int i=1;i<=m;i++)
    		for(int j=1;j<=tot;j++)
    			if(dis(id[j],i)/V+tme[j]<=mid) G[i].push_back(j);
    }
    
    bool dfs(int x)
    {
        for(auto y:G[x])
            if(!vis[y])
            {//puts("?");
                vis[y]=1;
                if(!match[y] || dfs(match[y]))
                {
                    match[y]=x;
                    return true ;
                }
            }
        return false ;
    }
    
    bool check(double mid)
    {
        init(mid);
        for(int i=1;i<=m;i++)
        {
            memset(vis,0,sizeof(vis));
       	    if(!dfs(i)) return false ;
        }
        return true ;
    }
    
    int main()
    {
    	//freopen("my.out","w",stdout);
        n=read(),m=read(),T1=read(),T2=read(),V=read(); 
        for(int i=1;i<=m;i++) mx[i]=read(),my[i]=read();
        for(int i=1;i<=n;i++) tx[i]=read(),ty[i]=read();
    	T1/=60,tot=n*m;
    
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=tot;j++)
    		{
    			int k=(i-1)*m+j;
    			id[k]=i,tme[k]=(j-1)*(T1+T2)+T1;
    		}
    
        double l=T1,r=1e5;
        while(l+EPS<r)
        {
            double mid=(l+r)/2;
            if(check(mid))
                r=mid;
            else l=mid;
            
            //break ;
        }
        printf("%.6lf
    ",r);
    
        return 0;
    }
    

    POJ1325 Machine Schedule

    因为机器一开始模式是0,所以a[i]或b[i]为0的不会使机器重启,所以不要加边。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=110,M=1010;
    
    int head[N],to[M],nxt[M];
    int match[M],vis[M];
    int n,m,k,num,ans;
    
    void add(int x,int y)
    {
    	nxt[++num]=head[x],to[num]=y,head[x]=num;
    }
    
    bool dfs(int x)
    {
    	for(int i=head[x],y; i!=-1; i=nxt[i])
    		if(!vis[y=to[i]])
    		{//puts("?");
    			vis[y]=1;
    			if(match[y]==-1 || dfs(match[y]))
    			{
    				match[y]=x;
    				return true ;
    			}
    		}
    	return false ;
    }
    
    int main()
    {
    	while(scanf("%d",&n)!=EOF && n)
    	{
    		scanf("%d%d",&m,&k);
    		ans=num=0;
    		memset(match,-1,sizeof match);
    		memset(head,-1,sizeof head);
    		for(int i=1;i<=k;i++)
    		{
    			int a,x,y; scanf("%d%d%d",&a,&x,&y);
    			if(x && y) add(x,y+n);
    		}
    	
    		for(int i=0;i<n;i++)
    		{
    			memset(vis,0,sizeof vis);
    			if(dfs(i)) ans++;
    		}
    		cout<<ans<<endl;
    	}
    }
    

    POJ2226

    二分图的最小点覆盖

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #define fi first
    #define se second
    #define Pit pair<int,int>
    using namespace std;
    typedef long long LL;
    const int N=55;
    
    int read()
    {
    	int x=0,p=1; char ch=getchar();
    	while((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    	if(ch=='-') p=-1,ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    	return x*p;
    }
    /*-----------------------------------------------------------------*/
    
    vector<int> G[N*N];
    char s[N][N];
    int a1[N][N],a2[N][N],vis[N*N],match[N*N];
    int n,m,cntn,cntm,ans;
    
    bool dfs(int x)
    {
    	for(auto y:G[x])
    		if(!vis[y])
    		{
    			vis[y]=1;
    			if(!match[y] || dfs(match[y]))
    			{
    				match[y]=x; return true ;
    			}
    		}
    	return false ;
    }
    
    int main()
    {
    	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    
    	n=read(),m=read();
    	for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
    
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=m;j++)
    			if(s[i][j]=='*')
    			{
    				if(s[i][j-1]!='*') cntn++;
    				a1[i][j]=cntn;
    			}
    	}
    	for(int j=1;j<=m;j++)
    	{
    		for(int i=1;i<=n;i++)
    			if(s[i][j]=='*')
    			{
    				if(s[i-1][j]!='*') cntm++;
    				a2[i][j]=cntm+cntn;
    			}
    	}
    
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			if(a1[i][j] && a2[i][j]) G[a1[i][j]].push_back(a2[i][j]);
    
    	for(int i=1;i<=cntn;i++)
    	{
    		memset(vis,0,sizeof vis);
    		ans+=dfs(i);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

  • 相关阅读:
    树---对称的二叉树
    树---二叉树的下一个节点
    阿里一面电话面
    树---重建二叉树
    CVTE电话面
    聊聊平台型游戏
    Ogre-next with Visual Studio 2019, SDL Memset, CL.exe error
    中国能不能制作AAA游戏?
    Simple Cel Shading 钟馗
    Modeling -> Mixamo auto rigging -> UE4 retargeting
  • 原文地址:https://www.cnblogs.com/lzqlalala/p/11224936.html
Copyright © 2020-2023  润新知