社区讨论
实在是走投无路了
学术版参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lobotmy7
- 此快照首次捕获于
- 2023/10/30 00:30 2 年前
- 此快照最后确认于
- 2023/11/04 05:12 2 年前
POJ 2114,蜜汁TLE,调了三天了
只求大佬帮忙分析一下我的代码的复杂度,不胜感激!
CPP#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
// set s.insert(x) , set s.find(x) set s.count(x)
using namespace std;
const int maxn = 1e4 + 5,maxm = 1e2 + 5;
struct node {
int id,x;
friend bool operator < (node a,node b) {
return a.x < b.x;
}
};
int first1[maxn << 1],last1[maxn << 1],dx1[maxn << 1],nxt1[maxn << 1],w1[maxn << 1],xb1; // for real
int first2[maxn << 1],last2[maxn << 1],dx2[maxn << 1],nxt2[maxn << 1],xb2; // for core
int n,x,y,minn,minid,sz[maxn],tot,rt,req[maxm],m,b[maxn],col[maxn];
bool used[maxn],ans[maxm];
multiset<node> v[maxn];
inline int read() {
int x = 0,f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -f;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
if (f > 0)
return x; else
return -x;
}
inline void init() {
for (int i=0; i<=xb1; i++)
first1[i] = nxt1[i] = 0;
for (int i=0; i<=xb2; i++)
first2[i] = nxt2[i] = 0;
rt = xb1 = xb2 = m = x = y = tot = 0;
for (int i=0; i <=n; i++) {
v[i].clear();
used[i] = 0;
}
}
inline void build1(int x,int y,int z) {
dx1[++xb1] = y,w1[xb1] = z;
if (!first1[x])
first1[x] = xb1; else
nxt1[last1[x]] = xb1;
last1[x] = xb1;
}
inline void build2(int x,int y) {
dx2[++xb2] = y;
if (!first2[x])
first2[x] = xb2; else
nxt2[last2[x]] = xb2;
last2[x] = xb2;
}
inline void dfs_core1(int x,int fa) { //统计当前子树有多少个节点
tot++;
for (int i=first1[x]; i; i = nxt1[i]) {
int y = dx1[i];
if (used[y] || y == fa)
continue;
dfs_core1(y,x);
}
}
inline void dfs_core2(int x,int fa) { //确定该子树的重心
int maxx = 0;
sz[x] = 1;
for (int i=first1[x]; i; i = nxt1[i]) {
int y = dx1[i];
if (used[y] || y == fa)
continue;
dfs_core2(y,x);
maxx = max(maxx,sz[y]);
sz[x] += sz[y];
}
maxx = max(maxx,tot - sz[x]);
if (maxx < minn) {
minn = maxx;
minid = x;
}
}
inline int get_core(int x) { // 寻找当前子树的重心
minn = 1e9,tot = 0;
dfs_core1(x,0);
dfs_core2(x,0);
return minid;
}
inline void dfs(int x,int fa) { //构建点分树
int tmp = get_core(x);
if (rt) {
build2(fa,tmp);
build2(tmp,fa);
}
if (!rt)
rt = tmp;
used[tmp] = 1;
for (int i=first1[tmp]; i; i = nxt1[i]) {
int y = dx1[i];
if (used[y])
continue;
dfs(y,tmp);
}
}
inline void get_number(int org,int x,int pre,int dis) {
v[org].insert((node){col[x],dis});
for (int i=first1[x]; i; i = nxt1[i]) {
int y = dx1[i];
if (y == pre || used[y])
continue;
get_number(org,y,x,dis + w1[i]);
}
}
void get_col(int x,int org,int pre) {
col[x] = org;
for (int i = first1[x]; i; i = nxt1[i]) {
int y = dx1[i];
if (y == pre || used[y])
continue;
get_col(y,org,x);
}
}
inline void handle(int x,int fa) {
used[x] = 1;
for (int i=first2[x]; i; i = nxt2[i]) {
int y = dx2[i];
if (y == fa)
continue;
get_col(y,y,0);
}
get_number(x,x,0,0);
for (int i=first2[x]; i; i = nxt2[i]) {
int y = dx2[i];
if (y == fa)
continue;
handle(y,x);
}
}
inline void work(int x,int fa) {
vector<node> l;
l.clear();
for (multiset<node>::iterator it = v[x].begin(); it != v[x].end(); it++)
l.push_back((*it));
int len = l.size();
vector<int> tmp;
tmp.clear();
for (int q = 1; q <= m; q++) {
int last = len - 1;
int p = req[q];
if (ans[q])
continue;
for (int i = 0; i < len && (!ans[q]); i++) {
if (i > 0 && l[i].x != l[i - 1].x) {
for (int j = 0; j < tmp.size(); j++)
b[tmp[j]]--;
tmp.clear();
} else {
if (tmp.size() - b[l[i].id] > 0) {
ans[q] = 1;
break;
}
}
while (l[last].x + l[i].x > p && last > 0)
last--;
if (last == 0 && l[last].x + l[i].x > p)
break;
while (l[last].x + l[i].x == p) {
b[l[last].id]++;
tmp.push_back(l[last].id);
if (last > 0)
last--;
if (last == 0)
break;
}
if (tmp.size() - b[l[i].id] > 0)
ans[q] = 1;
}
for (int i=0; i<tmp.size(); i++)
b[tmp[i]]--;
tmp.clear();
}
for (int i = first2[x]; i; i = nxt2[i]) {
int y = dx2[i];
if (y == fa)
continue;
work(y,x);
}
}
int main() {
// freopen("poj2114.in","r",stdin);
// freopen("poj2114.out","w",stdout);
int o = 0;
while (1 == 1) {
n = read();
if (n == 0)
break;
for (int i=1; i <= n; i++) {
x = read();
while (x) {
y = read();
build1(i,x,y);
build1(x,i,y);
x = read();
}
}
dfs(1,0);
for (int i=0; i<=n; i++)
used[i] = 0;
col[rt] = rt;
handle(rt,0);
int tmp = read();
while (tmp) {
req[++m] = tmp;
tmp = read();
}
work(rt,0);
for (int i=1; i<=m; i++) {
if (ans[i] || req[i] == 0) {
puts("AYE");
ans[i] = 0;
} else
puts("NAY");
}
puts(".");
init();
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...