题目链接
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\n",ans);
return 0;
}