zoukankan      html  css  js  c++  java
  • 二分图总结

    1. 二分图的判定:染色法。(O(n+m))

    void dfs(int x)
    {
    	int i,j;
    	for(i=head[x];i;i=e[i].nxt)
    	{
    		int to=e[i].to;
    		if(!c[to])
    		{
    			c[to]=3-c[x];
    			dfs(to);
    		}
    		else if(c[to]==c[x])
    		{
    			pd=0;
    			return;
    		}
    	}
    }
    

    2. 二分图最大匹配:

    匈牙利算法(增广路算法): (O(n*m))

    dinic(网络流算法):(O(sqrt n*m))

    bool dfs(int x)
    {
    	int i,j;
    	vis[x]=1;
    	for(i=head[x];i;i=a[i].nxt)
    	{
    		int to=a[i].to;
    		if(vis[to]) continue;
    		vis[to]=1;
    		if(!match[to]||dfs(match[to]))
    		{
    			match[to]=x;
    			return true;
    		}
    	}
    	return false;
    }
    for(i=1;i<=n;i++)
    {
    	memset(vis,0,sizeof(vis));
    	if(dfs(i)) ans++;
    }
    

    3. 最小点覆盖=最大匹配


    4. 最大独立集=总点数-最大匹配


    5. 有向无环图中:

    a. 最小边覆盖=最小路径点覆盖:

    选取最少的路径,使得每个定点均属于一条路径,路径长度可以为0。

    与二分图的关系:将每个点拆成入点和出点,最小路径覆盖=原图总点数-拆点后的图的最大匹配

    b. 最大团:任意两点之间都有边相连的最大子图

    无向图(G)的最大团等于它补图的最大独立集。

    c. 最小路径可重点覆盖

    有向无环图(G)的最小路径可重点覆盖,等价于先对有向图传递闭包,得到有向无环图(G'),再在(G')上求一般的(路径不可相交的)最小路径点覆盖。


    6. 可用网络流dinic求解

    例:「UVA1411」Ants:

    因为两条相交线段长度必然大于分别直接相连,所以答案就是二分图上跑最小费用流,使用类dinic算法,时间复杂度上届为(O(nmf))(f)为流量。

    #include<bits/stdc++.h>
    #define ll long long
    #define N 500
    #define M 600000
    #define eps 1e-5
    using namespace std;
    int head[N],n,cnt=2,S,T,inf=1e9+7,vis[N];
    struct note{
    	double x,y;
    }b[N],W[N];
    struct edge{
    	int to,nxt,sz;
    	double w;
    }a[M];
    void add(int x,int y,int s,double z)
    {
    	a[cnt].to=y;
    	a[cnt].sz=s;
    	a[cnt].nxt=head[x];
    	a[cnt].w=z;
    	head[x]=cnt++;
    	if(s!=0) add(y,x,0,-z);
    }
    double calc(note x,note y){
    	return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
    } 
    int ans=inf;
    double dis[N];
    deque<int> q;
    bool spfa()
    {
    	int i,j;
    	memset(vis,0,sizeof(vis));
    	for(i=S;i<=T;i++) dis[i]=inf;
    	while(!q.empty()) q.pop_front();
    	q.push_back(S);dis[S]=0;
    	vis[S]=1;
    	while(!q.empty())
    	{
    		int now=q.front();q.pop_front();
    		vis[now]=0;
    		for(i=head[now];i;i=a[i].nxt)
    		{
    			int to=a[i].to;
    			if(a[i].sz&&dis[to]-dis[now]-a[i].w>eps)
    			{
    				dis[to]=dis[now]+a[i].w;
    				if(!vis[to])
    				{
    					vis[to]=1;
    					if(!q.empty()&&dis[to]<dis[q.front()]) q.push_front(to);
    					else q.push_back(to);
    				}
    			}
    		}
    	}
    	return dis[T]!=inf;
    }
    int cur[N];
    int cost=0,maxflow;
    int dinic(int x,int flow)
    {
    	int i,j,sum=0;
    	vis[x]=1;
    	if(x==T||!flow) return flow;
    	for(i=cur[x];i;i=a[i].nxt)
    	{
    		cur[x]=i;
    		int to=a[i].to;
    		if(fabs(dis[to]-dis[x]-a[i].w)<eps&&a[i].sz&&!vis[to])
    		{
    			int f=dinic(to,min(a[i].sz,flow-sum));
    			if(!f) continue;
    			sum+=f;
    			a[i].sz-=f;
    			a[i^1].sz+=f;
    			cost+=f*a[i].w;
    			if(!flow) break;
    		}
    	}
    	return sum;
    }
    void solve()
    {
    	while(spfa())
    	{
    		vis[T]=1;
    		while(vis[T])
    		{
    			memcpy(cur,head,sizeof(head));
    			memset(vis,0,sizeof(vis)); 
    			maxflow+=dinic(S,inf);
    			ans=min(ans,cost);
    		}
    	}
    }
    int main()
    {
    	int i,j;
    	scanf("%d",&n);
    	for(i=1;i<=n;i++) scanf("%lf%lf",&b[i].x,&b[i].y);
    	for(i=1;i<=n;i++) scanf("%lf%lf",&W[i].x,&W[i].y);
    	for(i=1;i<=n;i++)
    	{
    		for(j=1;j<=n;j++)
    		{
    		//	if(i==j) continue;
    			double D=calc(b[i],W[j]);
    			add(i,j+n,1,D);
    		}
    	}
    	S=0,T=2*n+1;
    	for(i=1;i<=n;i++)
    	{
    		add(S,i,1,0);
    		add(i+n,T,1,0); 
    	}
    	solve();
    	for(i=1;i<=n;i++)
    	{
    		for(j=head[i];j;j=a[j].nxt)
    		{
    			int to=a[j].to;
    			if(!a[j].sz)
    			{
    				printf("%d
    ",to-n);
    			    break;
    			} 
    		}
    	}
    	return 0;
    } 
    
  • 相关阅读:
    Delphi的几个跨平台小游戏例子。
    Delphi判断某个类是否实现了某个接口
    Delphi RAD Server 应用服务基础平台
    Delphi XE10.1 引用计数
    运行Delphi XE10的MongoDB例程,测试Delphi插入记录性能
    在Windows下编译mongo-c-driver 1.3.x
    Delphi 高效读写锁
    Delphi XE10在 Android下调用静态库a文件
    Delphi 调试连接 任意Android手机/平板/盒子
    Some cool FireMonkey multi-device components
  • 原文地址:https://www.cnblogs.com/yzxx/p/13901302.html
Copyright © 2011-2022 走看看