1. 等式方程的可满足性
题目:给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:”a==b” 或 “a!=b”。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。
只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。
示例:
输入:[“a==b”,”b!=c”,”c==a”]
输出:false
//my solution
class Solution {
private:
unordered_map<char,char> parent;
public:
char findAncestor(char c){
char cc = c;
while(parent[c]!=0){
c= parent[c];
}
if(cc!=c) parent[cc] = c; //完全优化
return c;
}
void unionset(char a, char b){
char ac = findAncestor(a);
char bc = findAncestor(b);
if(ac != bc) parent[bc] = ac;
return ;
}
bool unionset_check_no_eq(char a, char b){
char ac = findAncestor(a);
char bc = findAncestor(b);
return bc != ac;
}
static bool cmp(string a, string b){
return a[1] > b[1];
}
bool equationsPossible(vector<string>& equations) {
int num = equations.size();
char a,b;
sort(equations.begin(),equations.end(),cmp);
for(int i=0;i<num;i++){
a = equations[i][0];
b = equations[i][3];
if(equations[i][1] == '=') unionset(a,b);
else if(!unionset_check_no_eq(a,b)){
return false;
}
}
return true;
}
};
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)求出最大的子集合。
#include <bits/stdc++.h>
using namespace std;
class UFS{
public:
vector<int> f, cnt;//f[] 保存父亲,cnt保存集合中节点数量
UFS(int n):f(n),cnt(n,1){
for(int i = 0; i < n; ++i){
f[i] = i;
}
}
int find(int i){
if(f[i] == f[f[i]])
return f[i];
else{
f[i] = f[f[i]];//折半优化
return find(f[i]);
}
}
void my_union(int x, int y){
int px = find(x);
int py = find(y);
if(px == py) return;
else{
f[px] = py;
cnt[py] = cnt[px] + cnt[py];
}
}
};
int main(){
int n;
cin>>n;
UFS u(n + 1);
vector<int> root;
for(int i = 0; i < n - 1; ++i){
int x,y;
cin>>x>>y;
if(x == 1)
root.push_back(y);
else if(y == 1)
root.push_back(x);
else
u.my_union(x, y);
}
int count = 0;
for(int i = 0; i < root.size(); ++i){
count = max(count, u.cnt[u.find(root[i])]);
}
cout<<count;
}