Session in BSU CodeForces - 1027F(思维 树 基环树 离散化)

时间:2022-09-28 23:11:37

题意:

  有n门考试,每门考试都有两个时间,存在几门考试时间冲突,求考完所有的考试,所用的最后时间的最小值

 解析:

  对于时间冲突的考试 就是一个联通块 把每个考试看作边,两个时间看作点,那么时间冲突的考试即为一个连通块

  对于一个连通块

  1、如果边数等于点数 即为一个基环树,那么明显 这个连通块的最后时间为 权值最大的点

  2、如果边数小于点数 即为一个树,那么连通块的最后时间为 权值次大的点(画画图)

  3、如果边数大于点数 那么就冲突了, 输出-1就好了

  离散化一下

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define pd(a) printf("%d\n", a);
#define plld(a) printf("%lld\n", a);
#define pc(a) printf("%c\n", a);
#define ps(a) printf("%s\n", a);
#define MOD 2018
#define LL long long
#define ULL unsigned long long
using namespace std;
const int maxn = 2e6+, INF = 0x7fffffff;
int n, not_pass, s, t, ans;
LL mx, mxx;
int head[maxn], cnt, vis[maxn], d[maxn];
LL a[maxn], b[maxn];
vector<LL> v;
int get_id(LL x) { return lower_bound(v.begin(), v.end(), x) - v.begin(); }
struct node
{
int u, v, next;
}Node[maxn]; void add_(int u, int v)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].next = head[u];
head[u] = cnt++;
} void add(int u, int v)
{
add_(u, v);
add_(v, u);
}
void init()
{
mem(head, -);
cnt = ;
} void dfs(int u, int pa)
{
vis[u] = ;
if(v[u] >= mx) mxx = mx, mx = v[u];
else mxx = max(mxx, v[u]);
for(int i=head[u]; i!=-; i=Node[i].next)
{
node e = Node[i];
if(e.v == pa) continue;
if(!vis[e.v]) d[e.v] = d[u] + , dfs(e.v, u);
else
{
if(d[e.v] > d[u]) ans++;
}
}
} int main()
{
init();
rd(n);
rep(i, , n)
{
rd(a[i]), rd(b[i]);
v.push_back(a[i]);
v.push_back(b[i]);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for(int i=; i<n; i++)
add(get_id(a[i]), get_id(b[i]));
int len = v.size();
LL res = -INF;
for(int i=; i<len; i++)
{
mx = mxx = ans = ;
if(vis[i]) continue;
dfs(i, -);
if(ans >= )
{
puts("-1");
return ;
}
if(ans == )
res = max(res, mx);
else if(ans == )
{
res = max(res, mxx);
// cout<< mxx << " " << mx << endl;
}
}
// cout<< mxx << " " << endl;
pd(res); return ;
}