资讯详情

【题解】[CQOI2008] 传感器网络/二分图匹配最小字典序

我整个下午都在调整魔芋

以后再来说说这个算法的原理。

理论上,这种做法可以处理一切 问题。

#include<bits/stdc .h> #define inf 0x3f3f3f3f using namespace std; const int N=55*55; //判断是否存在匹配包含 (u,v)  ///看是否有环 //如果有环,则取反所有路径 //**然后删掉 (u,v) 这条边** //适用于完美匹配 -> 拆点 建虚点  int n,match[N],dfn[N],l[N],r[N],cnt,num,in[N],id[N]; char ch[55]; vector<int> g[N],g2[N]; //dfn 标记在右节点  bool dfs(int u) { 
         for(auto v:g2[u]) { 
          if(dfn[v]==num) continue;   dfn[v]=num;   if(match[v]==-1||dfs(match[v])) { 
           match[v]=u;
			return 1;
		}
	}
	return 0;
} 
int dfs(int u,int topf) { 
       
	for(auto v:g2[u]) { 
       
		if(dfn[v]==num) continue;
		dfn[v]=num;
		if(match[v]==topf||(match[v]>topf&&dfs(match[v],topf)!=-1)) { 
       
			match[v]=u;
			return v;
		}
	}
	return -1;
}
bool check(int mid) { 
       
	cnt=0;
	for(int i=0;i<n;i++) in[i]=mid;
	in[n]=n;
	for(int i=0;i<=n;i++) { 
       
		l[i]=cnt;
		for(int j=1;j<=in[i];j++) { 
       
			id[cnt++]=i;
		}
		r[i]=cnt;
	}
	for(int i=0;i<n;i++) { 
       
		g2[i].clear();
	}
	for(int i=0;i<n;i++) { 
       
		for(auto j:g[i]) { 
       
			for(int k=l[j];k<r[j];k++) { 
       
				g2[i].push_back(k);
			}
		}
	}
	memset(match,-1,sizeof match);
	for(int i=0;i<=n-1;i++) { 
       
		num++;
		if(!dfs(i)) return 0;
	}
	return 1;
}
int main() { 
       
	scanf("%d",&n);
	scanf("%s",ch);
	for(int i=0;i<n;i++) { 
       
		char Ch[55]; scanf("%s",Ch);
		for(int j=0;j<n;j++) { 
       
			if(Ch[j]=='Y') { 
       
				g[i].push_back(j);
			}
		}
	}
	for(int i=0;i<n;i++) { 
       
		if(ch[i]=='Y') { 
       
			g[i].push_back(n);
		}
	}
	int l=0,r=n,res=0;
	while(l<=r) { 
       
		int mid=(l+r)/2;
		if(check(mid)) res=mid,r=mid-1;
		else l=mid+1;
	}
	check(res);
	for(int i=n;i<cnt;i++) { 
       
		for(int j=0;j<cnt;j++) { 
       
			g2[i].push_back(j);
		}
		dfs(i);
	}
	for(int i=0;i<n;i++) { 
       
		num++;
		printf("%d ",id[dfs(i,i)]);
	}
}

标签: 传感器dfs

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台