C 四个选项 并查集+深搜

题目链接:https://ac.nowcoder.com/acm/contest/5026/C

思路:本来有12道题,但是有些题得选择同一个选项;

   所以有些题可以归结为一道题;

   于是可以这样转换,把可以归为一题的归为一题,并且给上一个这道题包含的题目的数目;

   那么,这一步操作就需要并查集;

   然后,直接深搜就可以了;

   这道题直接告诉了我们搜索上限次数是“369600", 通过样例可知

   所以肯定不超时;

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[20];
 4 int base[20];
 5 int Search[20];
 6 int ans;
 7 int step;
 8 int Found(int u)
 9 {
10     if(f[u]==u) return u;
11     else{
12         f[u]=Found(f[u]);
13         return f[u];
14     }
15 }
16 void match(int t1,int t2)
17 {
18     int u=Found(t1);
19     int v=Found(t2);
20     if(u!=v){
21         if(u<v) f[v]=u;
22         else f[u]=v;
23     }
24 }
25 void init()
26 {
27     for(int i=1;i<=12;i++) f[i]=i;
28 }
29 void dfs(int ta,int tb,int tc,int td,int num)
30 {
31     if(num>step){
32         ans++;
33         return;
34     }
35     if(Search[num]<=ta) dfs(ta-Search[num],tb,tc,td,num+1);
36     if(Search[num]<=tb) dfs(ta,tb-Search[num],tc,td,num+1);
37     if(Search[num]<=tc) dfs(ta,tb,tc-Search[num],td,num+1);
38     if(Search[num]<=td) dfs(ta,tb,tc,td-Search[num],num+1);
39 }
40 int main()
41 {
42     init();
43     int a,b,c,d;
44     int m;
45     scanf("%d%d%d%d%d",&a,&b,&c,&d,&m);
46     while(m--){
47         int x,y;
48         scanf("%d%d",&x,&y);
49         if(x>y) swap(x,y);
50         match(x,y);
51     }
52     for(int i=1;i<=12;i++){
53         base[Found(i)]++;
54     }
55     for(int i=1;i<=12;i++){
56         if(base[i]){
57             step++;
58             Search[step]=base[i];
59         }
60     }
61     dfs(a,b,c,d,1);
62     printf("%d\n",ans);
63     return 0;
64 }
View Code

 

posted @ 2020-05-18 15:14  古比  阅读(170)  评论(0编辑  收藏  举报