1. 等式方程的可满足性

题目:给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:”a==b” 或 “a!=b”。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。
只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。
示例:
输入:[“a==b”,”b!=c”,”c==a”]
输出:false

  1. //my solution
  2. class Solution {
  3. private:
  4. unordered_map<char,char> parent;
  5. public:
  6. char findAncestor(char c){
  7. char cc = c;
  8. while(parent[c]!=0){
  9. c= parent[c];
  10. }
  11. if(cc!=c) parent[cc] = c; //完全优化
  12. return c;
  13. }
  14. void unionset(char a, char b){
  15. char ac = findAncestor(a);
  16. char bc = findAncestor(b);
  17. if(ac != bc) parent[bc] = ac;
  18. return ;
  19. }
  20. bool unionset_check_no_eq(char a, char b){
  21. char ac = findAncestor(a);
  22. char bc = findAncestor(b);
  23. return bc != ac;
  24. }
  25. static bool cmp(string a, string b){
  26. return a[1] > b[1];
  27. }
  28. bool equationsPossible(vector<string>& equations) {
  29. int num = equations.size();
  30. char a,b;
  31. sort(equations.begin(),equations.end(),cmp);
  32. for(int i=0;i<num;i++){
  33. a = equations[i][0];
  34. b = equations[i][3];
  35. if(equations[i][1] == '=') unionset(a,b);
  36. else if(!unionset_check_no_eq(a,b)){
  37. return false;
  38. }
  39. }
  40. return true;
  41. }
  42. };

2. 树——树形体育场紧急疏散

题目:体育场突然着火了,现场需要紧急疏散,但是过道真的是太窄了,同时只能容许一个人通过。现在知道了体育场的所有座位分布,座位分布图是一棵树,已知每个座位上都坐了一个人,安全出口在树的根部,也就是1号结点的位置上。其他节点上的人每秒都能向树根部前进一个结点,但是除了安全出口以外,没有任何一个结点可以同时容纳两个及以上的人,这就需要一种策略,来使得人群尽快疏散,问在采取最优策略的情况下,体育场最快可以在多长时间内疏散完成。
输入描述:
第一行包含一个正整数n,即树的结点数量(1<=n<=100000)。 接下来有n-1行,每行有两个正整数x,y,表示在x和y结点之间存在一条边。(1<=x,y<=n)
输出描述:
输出仅包含一个正整数,表示所需要的最短时间

示例1:
输入
6
2 1
3 2
4 3
5 2
6 1
输出
4
算法思想:
(1)将次根节点依次加入集合。
(2)求出最大的子集合。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. class UFS{
  4. public:
  5. vector<int> f, cnt;//f[] 保存父亲,cnt保存集合中节点数量
  6. UFS(int n):f(n),cnt(n,1){
  7. for(int i = 0; i < n; ++i){
  8. f[i] = i;
  9. }
  10. }
  11. int find(int i){
  12. if(f[i] == f[f[i]])
  13. return f[i];
  14. else{
  15. f[i] = f[f[i]];//折半优化
  16. return find(f[i]);
  17. }
  18. }
  19. void my_union(int x, int y){
  20. int px = find(x);
  21. int py = find(y);
  22. if(px == py) return;
  23. else{
  24. f[px] = py;
  25. cnt[py] = cnt[px] + cnt[py];
  26. }
  27. }
  28. };
  29. int main(){
  30. int n;
  31. cin>>n;
  32. UFS u(n + 1);
  33. vector<int> root;
  34. for(int i = 0; i < n - 1; ++i){
  35. int x,y;
  36. cin>>x>>y;
  37. if(x == 1)
  38. root.push_back(y);
  39. else if(y == 1)
  40. root.push_back(x);
  41. else
  42. u.my_union(x, y);
  43. }
  44. int count = 0;
  45. for(int i = 0; i < root.size(); ++i){
  46. count = max(count, u.cnt[u.find(root[i])]);
  47. }
  48. cout<<count;
  49. }