codeforces1027F. Session in BSU

题目链接

codeforces1027F. Session in BSU

题解

二分图匹配就fst了....显然是过去的,不过tle test87估计也pp了,好坑
那么对于上面做匹配的这个二分图分情况讨论一下
考虑当前的联通块:
边数大于点数:这样肯定是无解的
边数 = 点数:这是一棵基环树,每个日期都会被用,输出最大值
边数 < 点数:这是一棵树,输出次大值
并查集维护一下联通块

代码

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
inline int read() { 
	int x = 0,f = 1; 
	char c = getchar(); 
	while(c < '0' || c > '9'){if(c == '-')f = -1; c = getchar(); } 
	while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
	return x *f ; 
} 
const int maxn = 2000007; 
int a[maxn],b[maxn],ha[maxn << 1]; 	int n; 

/*struct node { 
	int v,next;
}edge[maxn << 1]; 
int head[maxn << 1],num = 0; 
inline void add_edge(int u,int v) { 
	edge[++ num].v = v; edge[num].next = head[u];head[u] = num; 
} 
int link[maxn << 1],vis[maxn << 1]; 
bool match(int x,int fa) { 
	for(int i = head[x];i;i = edge[i].next) { 
		int v = edge[i].v; 
		if(vis[v] != fa) { 
			vis[v] = fa; 
			if(!link[v] || match(link[v],fa)) { 
				link[v] = x; 
				return true; 
			} 
		} 
			
	} 
	return false; 
} */ 
int fa[maxn << 1];  
int mx[maxn << 1],mx2[maxn << 1]; 
int tag[maxn << 1]; 
inline int find(int x) { 
	if(fa[x] != x) fa[x] = find(fa[x]); 
	return fa[x]; 
} 
int main()  { 
	n = read(); 
	int num = 0; 
	for(int i = 1;i <= n;++ i) { 
		a[i] = read();b[i] = read(); 
		ha[++ num] = a[i],ha[++ num] = b[i]; 
	} 
	std::sort(ha + 1,ha + num + 1); 
	int len = std::unique(ha + 1,ha + num + 1) - ha - 1; 
	for(int i = 1;i <= n;++ i) { 
		a[i] = std::lower_bound(ha + 1,ha + len + 1,a[i]) - ha; 
		b[i] = std::lower_bound(ha + 1,ha + len + 1,b[i]) - ha; 
	} 
	for(int i = 1;i <= len;++ i) fa[i] = i, mx[i] = i;
	for(int i = 1;i <= n;++ i) { 
		int x = find(a[i]),y = find(b[i]); 
		if(x != y) {
			fa[y] = x; 
			if(tag[y]) tag[x] = 1; 
			if(mx[y] > mx[x]) mx2[x] = std::max(mx2[x],std::max(mx2[y], mx[x])),mx[x] = mx[y]; 
			else mx2[x] = std::max(mx2[x],mx[y]); 
		} 
		else if(!tag[x]) tag[x] = 1; 
		else { 
			puts("-1") ; 
			return 0; 
		}	
	} 
	int ans = 0;  
	for(int i = 1; i <= len; i++) {
		int k = find(i); 
		if(tag[k]) ans = std::max(ans,ha[mx[k]]);
		else ans = std::max(ans,ha[mx2[k]]);
	} 
	printf("%d
",ans); 
	return 0; 
} 
原文地址:https://www.cnblogs.com/sssy/p/9649179.html