[CF1027F] Session in BSU

题目传送门

洛谷 (有翻译)

网上有用dfs或者二分图匹配什么的,感觉略显复杂。

这道题可以用并查集解决。

把每个考试对应的两个时间连起来。

连的时候判断无解的情况,还有(暂时)有解的两种情况就行了:

祖先是0的已经不能取了,如果两个都不行就无解。

一个不行就必须取另一个。

两个都行,暂时取最小的。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int n;
 7 
 8 struct data
 9 {
10     int rv,v,id;
11 }dt[2000005];
12 
13 int cmp(data q,data w)
14 {
15     return q.rv<w.rv;
16 }
17 
18 int cmpb(data q,data w)
19 {
20     if(q.id==w.id)return q.v<w.v;
21     return q.id<w.id;
22 }
23 
24 int rw[2000005];
25 int f[2000005];
26 int p[2000005][2];
27 
28 int findfa(int x)
29 {
30     if(f[x]==x)return x;
31     f[x]=findfa(f[x]);
32     return f[x];
33 }
34 
35 int main()
36 {
37     scanf("%d",&n);
38     for(int i=1;i<=n;i++)
39     {
40         scanf("%d%d",&dt[2*i-1].rv,&dt[2*i].rv);
41         dt[2*i-1].id=dt[2*i].id=i;
42     }
43     sort(dt+1,dt+2*n+1,cmp);
44     for(int i=1;i<=2*n;i++)
45     {
46         if(dt[i].rv==dt[i-1].rv)dt[i].v=dt[i-1].v;
47         else dt[i].v=dt[i-1].v+1,rw[dt[i].v]=dt[i].rv;
48     }
49     for(int i=1;i<=dt[2*n].v;i++)f[i]=i;
50     sort(dt+1,dt+2*n+1,cmpb);
51     for(int i=1;i<=2*n;i++)p[(i+1)/2][!(i&1)]=dt[i].v;
52     int ans=-1;
53     for(int i=1;i<=n;i++)
54     {
55         int f0=findfa(p[i][0]),f1=findfa(p[i][1]);
56         if((!f0)&&(!f1)){printf("-1");return 0;}
57         if(f0>f1)swap(f0,f1);
58         if((f0==f1)||(!f0)||(!f1))
59         {
60             ans=max(ans,rw[f0]);
61             f[f0]=f[f1]=0;
62         }else
63         {
64             ans=max(ans,rw[f0]);
65             f[f0]=f1;
66         }
67     }
68     printf("%d",ans);
69     return 0;
70 }

猜你喜欢

转载自www.cnblogs.com/eternhope/p/9852273.html
今日推荐