LA 3644易爆物

LA 3644易爆物

【题目描述】:有一些简单化合物,每种化合物由两种元素组成。但是,当车上存在k中化合物,而且存在k种元素,就会爆炸。现在依次向车上装载,装载序列由输入给出,当会某物品装载后爆炸时,就不会装载这个,最终统计有多少个物品没有被装载上。

【算法分析】:

首先这个问题不是线性描述的,而是解决多个变量之间的冲突问题。这时候,我们是不是就要想到用图论来解决了?首先看题目中给出的例子,如果AB、BC、CD、AD,放进去就会爆炸,而AB,BC,AD,放进去就不会爆炸,而这道题使容易引起歧义的。但后面的例子解决了这个问题。必须k种元素都参与到爆炸行为中来。那么,就像第一个例子,k种元素,没中元素出现的次数为2,联想到节点的度数,即k个节点,每个节点的度为2,那么满足这个模型的就是形成了一个环。那么判环用并查集解决就比较方便了。

 

【完整代码】:

LA 3644易爆物
 1 #include<iostream>
 2 
 3 #include<stdio.h>
 4 
 5 #include<string.h>
 6 
 7 #include<algorithm>
 8 
 9 #include<stdlib.h>
10 
11 #include<math.h>
12 
13 #include<queue>
14 
15 #include<vector>
16 
17 #include<map>
18 
19 #define MAXN 100000+10
20 
21 #define MAXM 20000+5
22 
23 #define oo 9556531
24 
25 #define eps 0.000001
26 
27 #define PI acos(-1.0)
28 
29 #define REP1(i,n) for(int i=0;i<(n);i++)
30 
31 #define REP2(i,n) for(int i=1;i<=(n);i++)
32 
33 using namespace std;
34 
35  
36 
37 int p[MAXN],ans;
38 
39 int find(int x)
40 
41 {
42 
43     return x==p[x]?x:p[x]=find(p[x]);
44 
45 }
46 
47 void merge(int x,int y)
48 
49 {
50 
51     int px=find(x),py=find(y);
52 
53     if (px!=py) p[px]=py;
54 
55     return;
56 
57 }
58 
59 void init()
60 
61 {
62 
63     ans=0;
64 
65     for(int i=1;i<MAXN;i++) p[i]=i;
66 
67 }
68 
69 int main()
70 
71 {
72 
73     int x,y;
74 
75     init();
76 
77     while(cin>>x)
78 
79     {
80 
81         if(x==-1) {cout<<ans<<endl;init();continue;}
82 
83         cin>>y;
84 
85         if (find(x)==find(y)) {ans++;continue;}
86 
87         merge(x,y);
88 
89     }
90 
91     return 0;
92 
93 }
94 
95  
LA 3644易爆物

 

             

【关键词】:图论建模,读题

LA 3644易爆物

上一篇:vim——打开多个文件、同时显示多个文件、在文件之间切换


下一篇:[最近要学知识点]