CF1027F Session in BSU
Posted bestfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1027F Session in BSU相关的知识,希望对你有一定的参考价值。
花絮:
这场看起来打得还不错的样子……(别问我是用哪个号打的)。
然后听说这题的思想被出了好多次,女生赛也出过,quailty算法,然而当时没反应过来,而且时间不多啦。
题意:
有n个人,每个人有两个时间点可以参加考试,任意两人不能再同意时间点参加考试。问最迟考试的人的考试时间最早是多少?
$nleq 10^6.$
题解:
离散化,将每人的两个时间点连边。题意可以转化为:给每条边定向满足任意一点入度至多为1,使得每条边指向的点的编号最大值最小。
要满足任意一点入度至多为1,原图必须是基环森林(每个连通块必须是基环树或树)。先判不合法的情况。然后对于每个连通块,如果是基环树,那么每个点一定有1的入度,用最大值更新答案;如果是树,那么最多使得根节点没有入度,其余点都有1的入度,所以把最大编号设为根,用次大值更新答案。每个连通块的值的最大值即为最终答案。
复杂度$mathcal{O}(nlog n)$。
代码实现可能不是很简洁明了(好像可以用并查集维护),不过思路是没错的。
code:
1 #include<bits/stdc++.h> 2 #define rep(i,x,y) for (int i=(x);i<=(y);i++) 3 #define ll long long 4 #define inf 1000000001 5 #define y1 y1___ 6 #define pii pair<int,int> 7 #define fi first 8 #define se second 9 using namespace std; 10 char gc(){ 11 static char buf[100000],*p1=buf,*p2=buf; 12 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 13 } 14 #define gc getchar 15 ll read(){ 16 char ch=gc();ll x=0;int op=1; 17 for (;!isdigit(ch);ch=gc()) if (ch==‘-‘) op=-1; 18 for (;isdigit(ch);ch=gc()) x=(x<<1)+(x<<3)+ch-‘0‘; 19 return x*op; 20 } 21 #define N 2000005 22 int n,sl,q[N],cnt=1,head[N],num,Mx,Mx2,vis[N],dep[N],ans; 23 struct edge{int to,nxt;}e[N]; 24 struct node{int x,y;}a[N]; 25 void adde(int x,int y){e[++cnt].to=y;e[cnt].nxt=head[x];head[x]=cnt;} 26 void dfs(int u,int pr){ 27 vis[u]=1; 28 if (q[u]>Mx) Mx2=Mx,Mx=q[u];else Mx2=max(Mx2,q[u]); 29 for (int i=head[u];i;i=e[i].nxt) if ((i^1)!=pr){ 30 int v=e[i].to; 31 if (!vis[v]) dep[v]=dep[u]+1,dfs(v,i); 32 else if (dep[u]>dep[v]) num++; 33 } 34 } 35 int main(){ 36 n=read();int x,y; 37 rep (i,1,n){ 38 q[++sl]=a[i].x=read(),q[++sl]=a[i].y=read(); 39 if (a[i].x>a[i].y) swap(a[i].x,a[i].y); 40 } 41 sort(&q[1],&q[sl+1]);sl=unique(&q[1],&q[sl+1])-q-1; 42 rep (i,1,n){ 43 a[i].x=lower_bound(&q[1],&q[sl+1],a[i].x)-q; 44 a[i].y=lower_bound(&q[1],&q[sl+1],a[i].y)-q; 45 adde(a[i].x,a[i].y);adde(a[i].y,a[i].x); 46 } 47 rep (i,1,sl) if (!vis[i]){ 48 num=Mx=Mx2=0; 49 dfs(i,0); 50 if (num>1) return puts("-1"),0; 51 if (num==1) ans=max(ans,Mx);else ans=max(ans,Mx2); 52 } 53 printf("%d ",ans); 54 return 0; 55 }
以上是关于CF1027F Session in BSU的主要内容,如果未能解决你的问题,请参考以下文章
Session in BSU CodeForces - 1027F(思维 树 基环树 离散化)
CF.1027F.Session in BSU(思路 并查集)
[Codeforces Round49F] Session in BSU
Codeforces 1027F. Session in BSU