Closest Common Ancestors(poj 1470)
原题链接
题目类型:lca模板
使用tarjan来离线求取lca问题。
tarjan求lca
//TLE
#include<iostream>
#include<vector>
using namespace std;
#define NMAX 950
struct edge {
short from, to;
short lca, nxt;
};
vector<edge> E;
short h[NMAX];
vector<edge> Q;
short qh[NMAX];
short res[NMAX], du[NMAX], color[NMAX];
char vis[NMAX];
short n, m;
short root;
short find(short x) {
if (x != color[x]) color[x] = find(color[x]);
return color[x];
}
void tarjan(short x,short fa) {
vis[x] = 1;
color[x] = x;
for (short i = h[x]; i != -1; i = E[i].nxt) {
if (!vis[E[i].to]) {
tarjan(E[i].to,x);
}
}
color[x] = fa;
for (short i = qh[x]; i != -1; i = Q[i].nxt) {
if (vis[Q[i].to] && !Q[i].lca) {
short LCA = find(Q[i].to);
Q[i].lca = LCA;
Q[i ^ 1].lca = LCA;
res[LCA]++;
}
}
}
int main() {
while (~scanf_s("%d", &n)) {
memset(du, 0, sizeof(du));
memset(h, -1, sizeof(h));
memset(qh, -1, sizeof(qh));
memset(res, 0, sizeof(res));
Q.clear();
E.clear();
char c;
for (short i = 0; i < n; i++) {
short a, b, num;
scanf_s("%d:(%d)", &a, &num);
for (short j = 0; j < num; j++) {
scanf_s("%d", &b);
edge cur;
du[b]++;
cur.from = a, cur.to = b, cur.lca = 0, cur.nxt = h[a];
h[a] = E.size();
E.push_back(cur);
cur.from = b, cur.to = a, cur.lca = 0, cur.nxt = h[b];
h[b] = E.size();
E.push_back(cur);
}
}
for (short i = 1; i <= n; i++) {
if (!du[i]) {
root = i;
break;
}
}
cin >> m;
for (short i = 0; i < m; i++) {
short a, b;
scanf_s(" (%d %d)", &a, &b);
edge cur;
cur.from = a, cur.to = b, cur.lca = 0, cur.nxt = qh[a];
qh[a] = Q.size();
Q.push_back(cur);
cur.from = b, cur.to = a, cur.lca = 0, cur.nxt = qh[b];
qh[b] = Q.size();
Q.push_back(cur);
}
//首先自己染色自己
memset(vis, 0, sizeof(vis));
tarjan(root, root);
//for (short i = 0; i < Q.size(); i++) cout << Q[i].from << " " << Q[i].to << " " << Q[i].lca << endl;
for (short i = 1; i <= n; i++) {
if (res[i]) cout << i << ":" << res[i] << endl;
}
}
}
限时两秒,超时不应该呀,明天再看!
Shortest Prefixes(poj 2001)
原题链接
题目类型:tire字典树
错误思路一:逐位寻找,只有当该位的字符没有在其余字符串中出现时,表示可以作为前缀。
//wa
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string> S;
vector<string> R(1010);
vector<char> cur;
int main() {
string line;
FILE* stream;
freopen_s(&stream, "C:\\Users\\芙茗\\Desktop\\test2.in", "r", stdin);
while (getline(cin, line)) S.push_back(line);
for (int i = 0; i < 20; i++) {
cur.clear();
for (int j = 0; j < S.size(); j++) {
if (!R[j].size() && i < S[j].size()) cur.push_back(S[j][i]);
}
for (int j = 0; j < S.size(); j++) {
if (!R[j].size() && i < S[j].size()){
int num = count(cur.begin(), cur.end(), S[j][i]);
if((num == 1 || i == S[j].size() - 1)) R[j] = S[j].substr(0, i + 1);
}
}
}
for (int i = 0; i < S.size(); i++) cout << S[i] << " " << R[i] << endl;
}
错误思路二:爆搜 时间复杂度为O(1000100020),但是超时
//tle
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
vector<string> S;
vector<string> S2;
map<string,string> R;
vector<char> cur;
int main() {
string line;
//FILE* stream;
//freopen_s(&stream, "C:\\Users\\芙茗\\Desktop\\test2.in", "r", stdin);
while (getline(cin, line)) S.push_back(line), S2.push_back(line);
sort(S.begin(), S.end());
for (int i = 0; i < S.size(); i++) {
int lot=S[i].size();
for (int j = 1; j <= S[i].size(); j++) {
int key = 1;
for (int k = 0; k < S.size(); k++) {
if (k != i && S[i].substr(0, j) == S[k].substr(0, j)) key = 0;
}
if (key) {
lot = j;
break;
}
}
R[S[i]] = S[i].substr(0, lot);
}
for (int i = 0; i < S2.size(); i++) cout << S2[i] << " " << R[S2[i]] << endl;
}
思路三:采用字典树
#include<iostream>
#include<vector>
#include<string>
using namespace std;
vector<string> S;
struct node {
int count;
struct node* son[26];
//初始化函数
node() {
count = 0;
int i = 0;
for (; i < 26; i++) son[i] = NULL;
}
};
struct node* root;
void insert(string x) {
struct node* cur = root;
for (int i = 0; i < x.size(); i++) {
int num = x[i] - 'a';
if (cur->son[num] == NULL) {
cur->son[num] = new node;
++((cur->son[num])->count);
cur = cur->son[num];
}
else {
cur = cur->son[num];
++(cur->count);
}
}
}
void query(string x) {
struct node* cur = root;
string res;
for (int i = 0; i < x.size(); i++) {
int num = x[i] - 'a';
cur = cur->son[num];
if (cur->count == 1) {
res += x[i];
cout << x << " " << res << endl;
return;
}
res += x[i];
}
cout << x << " " << x << endl;
}
int main() {
//FILE* stream;
//freopen_s(&stream, "C:\\Users\\芙茗\\Desktop\\test2.in", "r", stdin);
string line;
while (getline(cin, line)) S.push_back(line);
root = new node;
for (int i = 0; i < S.size(); i++) {
insert(S[i]);
}
for (int i = 0; i < S.size(); i++) query(S[i]);
}