zoukankan      html  css  js  c++  java
  • 【纪中集训2019.3.23】Deadline

    题意

    描述

    一个二分图((A,B)),每个点额外有一个颜色0或者1;

    匹配时,只能相同颜色的点匹配;

    给出(A)中的颜色,问如何分配(B)种的颜色使得((A,B))的最大匹配最小;

    范围

    $1 le n , m le 2000 , 1 le k le 5000 $

    题解

    • (A)中的点按照标号划分为(v_0和v_1)

    • 将B中的点拆成(u_0)(u_1),(u_0)(u_1)连流量为(1)的边;

    • (S)(v_0)连流量为1的边,(v_1)向​(T)连流量为​(1)的边;

    • (v_0)向原图中相连的(u_0)(inf)边,(u_1)(v_1)(inf)边;

    • 简单说明:

    • 可以转化为一种标号使得最小点覆盖最小;

    • (<S,v_0> , <u_0,u_1> , <v_1,T>) 被割分别代表(v_0,u,v_1)被选入覆盖集;

    • 只需要说明割和合法方案等价:

    • 由于不存在一条从(S)(T)的残量路径,所以要么(u)被割了,要么(u)两边相连的点至少一边被割了;

    • 这和合法方案的条件是等价的;

    • 所以(ans)=最小割;

    • 考试的时候因为当初做网络流的时候没有理解深刻并且有太久没有做了,所以没有做出来;

      #include<bits/stdc++.h>
      #define inf 0x3f3f3f3f
      using namespace std;
      const int N=10010; 
      char gc(){
      	static char*p1,*p2,s[1000000];
      	if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
      	return(p1==p2)?EOF:*p1++;
      }
      int rd(){
      	int x=0;char c=gc();
      	while(c<'0'||c>'9')c=gc();
      	while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
      	return x;
      }
      int n,m,k,o,hd[N],p[N],S,T,d[N],vis[N],cur[N];
      struct Edge{int v,nt,f;}E[N<<1];
      void adde(int u,int v,int f){
      	E[o]=(Edge){v,hd[u],f};hd[u]=o++;
      	E[o]=(Edge){u,hd[v],0};hd[v]=o++;
      }
      bool bfs(){
      	static queue<int>q;
      	for(int i=S;i<=T;++i)d[i]=vis[i]=0;
      	while(!q.empty())q.pop();
      	d[S]=vis[S]=1;q.push(S);
      	while(!q.empty()){
      		int u=q.front();q.pop();
      		for(int i=hd[u];~i;i=E[i].nt)if(E[i].f){
      			int v=E[i].v;
      			if(vis[v])continue;
      			d[v]=d[u]+1;
      			q.push(v);
      			vis[v]=1;
      			if(v==T)return true;
      		}
      	}
      	return false;
      }
      int dfs(int u,int F){
      	if(u==T||!F)return F;
      	int flow=0,f;
      	for(int i=cur[u];~i;i=E[i].nt){
      		int v=E[cur[u]=i].v;
      		if(d[v]==d[u]+1&&(f=dfs(v,min(E[i].f,F)))){
      			flow+=f;F-=f;
      			E[i].f-=f;E[i^1].f+=f;
      			if(!F)break;
      		}
      	}
      	return flow;
      }
      int dinic(){
      	int flow=0;
      	while(bfs()){
      		for(int i=S;i<=T;++i)cur[i]=hd[i];
      		flow+=dfs(S,inf);
      	}
      	return flow;
      }
      int main(){
      	freopen("deadline.in","r",stdin);
      	freopen("deadline.out","w",stdout);
      	memset(hd,-1,sizeof(hd));
      	n=rd();m=rd();k=rd();S=0;T=n+m*2+1;
      	for(int i=1;i<=n;++i)if(p[i]=rd())adde(S,2*m+i,1);else adde(2*m+i,T,1);
      	for(int i=1;i<=m;++i)adde(i*2-1,i*2,1);
      	for(int i=1;i<=k;++i){
      		int u=rd(),v=rd();
      		if(p[u])adde(m*2+u,v*2-1,inf);
      		else adde(v*2,m*2+u,inf);
      	}
      	int ans=dinic();
      	cout<<ans<<endl;
      	return 0;
      }
      
  • 相关阅读:
    oracle之修改/忘记用户密码
    linux 使用错误总结
    oracle数据库之用户管理
    linux命令使用总结
    linux各种压缩包的压缩和解压方法
    logback将日志写入不同文件夹里
    nginx下配置多个web服务
    OKHttp3学习
    linux 发送 post 请求
    maven 项目下 Maven Dependencies 下列表为空
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10590741.html
Copyright © 2011-2022 走看看