$$AVICII$$

#惊奇建模<主仆见证了 Hobo 的离别>

1 新元件的编号等于融合之前元件的总个数加一。当然,参与融合的 K个元件融合之后依然存在,并且每个元件至多参与一次融合。
2 由于元件的容量有限,Eddie 没有能力唤醒 Hobo 全部的回忆,所以他会用下列两种方式来融合元件:
3 
4     集合的交:一段记忆存储在新的元件中,当且仅当这段记忆在参与融合的K 个元件中都有储存。
5     集合的并:一段记忆存储在新的元件中,当且仅当这段记忆在参与融合的至少一个元件中有储存。
主要题干

考试没留时间,(留时间估计也想不粗来,雾),我们考虑建图,一条有向边a指向b的意义是a包含b的内容,但考虑K==1的情况,实质上是新点和所给点的内容完全相同,那么建双向边。每次用dfs判断是否Y能到X。至于复杂度,(首先数据很水),其次,每个点只融合一次,两两造点的话,这个图的深度也很小。

 1 #include<cstdio>
 2 #include<iostream>
 3 #define MAXN 251000
 4 using namespace std;
 5 int N,M;
 6 struct rr{
 7     int nt,to;
 8 }bl[MAXN*30];int hd[MAXN*3],itot;
 9 void add(int x,int y){
10     bl[++itot].to=y;
11     bl[itot].nt=hd[x];
12     hd[x]=itot;
13 }
14 bool dfs(int u,int fa,int md){
15     if(u==md)return true;
16     for(int i=hd[u];i;i=bl[i].nt)
17         if(bl[i].to!=fa)
18             if(dfs(bl[i].to,u,md))return true;
19     return false;
20 }
21 int main(){
22     //freopen("da.in","r",stdin);
23     scanf("%d%d",&N,&M);
24     int knd,opt,K,X,Y,rt;
25     int num=N;
26     for(int i=1;i<=M;++i){
27         scanf("%d",&knd);
28         if(knd){
29             scanf("%d%d",&X,&Y);
30             printf("%d\n",dfs(Y,0,X));
31         }
32         else{
33             scanf("%d",&opt);
34             if(opt){
35                 scanf("%d",&K);++num;
36                 for(int i=1;i<=K;++i)scanf("%d",&rt),add(num,rt);
37                 if(K==1)add(rt,num);
38             }
39             else{
40                 scanf("%d",&K);++num;
41                 for(int i=1;i<=K;++i)scanf("%d",&rt),add(rt,num);
42                 if(K==1)add(num,rt);
43             }
44         }
45     }
46     return 0;
47 }
View Code

抽象建模很需要学

posted @ 2019-08-19 21:03  bootpuss  阅读(301)  评论(0编辑  收藏  举报