QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#193466 | #6861. Counter Strike | sususy | AC ✓ | 1928ms | 141124kb | C++14 | 5.4kb | 2023-09-30 17:13:23 | 2023-09-30 17:13:24 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
vector<int>edge[400005];
bool isk[400005], del[400005], vis[400005];
int h[400005];
int n, m, k;
inline int bfs(int s)
{
queue<int>q;
q.push(s);
vis[s] = true;
int cnt = 0;
while(!q.empty())
{
int u = q.front(); q.pop();
if(isk[u]) cnt++;
for(int v : edge[u])
if(!del[v] && !vis[v]) q.push(v), vis[v] = true;
}
return cnt;
}
inline bool check()
{
for(int i = 1; i <= n; i++)
if(!del[i])
{
del[i] = true;
for(int i = 1; i <= n; i++) vis[i] = false;
bool flag = true;
for(int u = 1; u <= n; u++)
if(!del[u] && !vis[u])
if(bfs(u) > 1){flag = false; break;}
del[i] = false;
if(flag) return true;
}
return false;
}
int Log2[400005];
inline void init()
{
Log2[1] = 0;
for(int i = 2; i <= 400002; i++) Log2[i] = Log2[i >> 1] + 1;
}
int st[800005][24];
int d[400005], sum[400005];
inline int Q(int l, int r)
{
const int k = Log2[r - l + 1];
return max(st[l][k], st[r - (1 << k) + 1][k]);
}
/*
namespace TREE
{
int dfn[400005], sz[400005], tot;
void dfs(int u, int fa)
{
dfn[u] = ++tot;
sum[dfn[u]] = d[u];
sz[dfn[u]] = 1;
for(int v : edge[u])
if(v != fa && !del[v] && vis[v])
{
dfs(v, u);
sum[dfn[u]] += sum[dfn[v]];
sz[dfn[u]] += sz[dfn[v]];
}
st[dfn[u]][0] = sum[dfn[u]];
}
inline bool check()
{
int cnt = 0, id = -1;
for(int i = 1; i <= n; i++) vis[i] = false;
for(int i = 1; i <= n; i++)
if(!del[i] && !vis[i])
{
if(bfs(i) > 1) cnt++, id = i;
if(cnt > 1) return false;
}
if(!(~id)) return true;
for(int i = 1; i <= n; i++) vis[i] = false, d[i] = sum[i] = dfn[i] = sz[i] = 0;
for(int i = 1; i <= n; i++)
for(int k = 0; k <= Log2[n] + 1; k++) st[i][k] = 0;
tot = 0;
int cntk = bfs(id);
for(int i = 1; i <= n; i++)
if(vis[i] && isk[i]) d[i] = 1;
dfs(id, id);
for(int k = 1; k <= Log2[tot] + 1; k++)
for(int i = 1; i <= tot; i++)
st[i][k] = max(st[i][k - 1], st[i + (1 << (k - 1))][k - 1]);
for(int i = 1; i <= tot; i++)
if(sum[i] >= cntk - 1 && Q(i + 1, i + sz[i] - 1) == 1) return true;
return false;
}
}
*/
vector<vector<int>> build_block_forest(int siz, vector<vector<int>>& edge)
{
vector<int> dfn(n + 1, 0), low(n + 1, 0);
vector<vector<int>> tr_edge((n + 1) << 1);
stack<int> st;
int cnt = 0, tot = siz;
auto dfs = [&dfn, &low, &edge, &tr_edge, &st, &cnt, &tot](auto&& self, int u) -> void
{
low[u] = dfn[u] = ++cnt;
st.push(u);
for(int v : edge[u])
if(!dfn[v])
{
self(self, v);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u])
{
++tot;
int w;
do
{
w = st.top(); st.pop();
tr_edge[tot].push_back(w), tr_edge[w].push_back(tot);
} while(w != v);
tr_edge[tot].push_back(u), tr_edge[u].push_back(tot);
}
}
else low[u] = min(low[u], dfn[v]);
};
dfs(dfs, 1);
return tr_edge;
}
namespace GRAPH
{
int id[400005], dfn[800005], sz[800005], tot, cc;
vector<vector<int>> nedge(400005), tr;
int dfs1(int u)
{
int res = isk[u];
id[u] = ++tot;
vis[u] = true;
for(int v : edge[u])
if(!del[v])
{
if(!vis[v]) res += dfs1(v);
nedge[id[u]].push_back(id[v]);
}
return res;
}
void dfs2(int u, int fa)
{
dfn[u] = ++cc;
sum[dfn[u]] = d[u];
sz[dfn[u]] = 1;
for(int v : tr[u])
if(v != fa)
{
dfs2(v, u);
sum[dfn[u]] += sum[dfn[v]];
sz[dfn[u]] += sz[dfn[v]];
}
st[dfn[u]][0] = sum[dfn[u]];
}
bool check()
{
int cnt = 0, index = -1;
tot = cc = 0;//
for(int i = 1; i <= n; i++) vis[i] = false;
for(int i = 1; i <= n; i++)
if(!del[i] && !vis[i])
{
if(bfs(i) > 1) cnt++, index = i;
if(cnt > 1) return false;
}
if(!(~index)) return true;
for(int i = 1; i <= n; i++) d[i] = sum[i] = vis[i] = id[i] = sz[i] = dfn[i] = 0, nedge[i].clear();
for(int i = 1; i <= n << 1; i++) dfn[i] = sz[i] = 0;
for(int i = 1; i <= n; i++)
for(int k = 0; k <= Log2[n] + 1; k++) st[i][k] = 0;
int cntk = dfs1(index);
tr = build_block_forest(tot, nedge);
for(int i = 1; i <= n; i++) d[i] = 0;
for(int i = 1; i <= n; i++)
if(isk[i] && id[i]) d[id[i]] = 1;
dfs2(1, 1);
for(int i = 1; i <= cc; i++) st[i][0] = sum[i];
for(int k = 1; k <= Log2[cc] + 1; k++)
for(int i = 1; i <= cc; i++)
st[i][k] = max(st[i][k - 1], st[i + (1 << (k - 1))][k - 1]);
for(int i = 1; i <= tot; i++)
if(sum[dfn[i]] >= cntk - 1 && Q(dfn[i] + 1, dfn[i] + sz[dfn[i]] - 1) == 1) return true;
return false;
}
}
int main()
{
init();
int T; scanf("%d", &T);
while(T--)
{
for(int i = 1; i <= n; i++) isk[i] = del[i] = vis[i] = h[i] = d[i] = sum[i] = GRAPH::id[i] = GRAPH::dfn[i] = GRAPH::sz[i] = 0, edge[i].clear();
scanf("%d%d%d", &n, &m, &k);
for(int i = 1, u, v; i <= m; i++)
{
scanf("%d%d", &u, &v);
edge[u].push_back(v), edge[v].push_back(u);
}
for(int i = 1; i <= k; i++){scanf("%d", &h[i]); isk[h[i]] = true;}
int l = 0, r = k - 1;
while(l <= r)
{
int mid = (l + r) >> 1;
for(int i = 1; i <= mid; i++) del[h[i]] = true;
/*
if(m == n - 1)
{
if(TREE::check()) r = mid - 1;
else l = mid + 1;
}
else
{
if(check()) r = mid - 1;
else l = mid + 1;
}
*/
if(GRAPH::check()) r = mid - 1;
else l = mid + 1;
for(int i = 1; i <= mid; i++) del[h[i]] = false;
}
printf("%d\n", l);
}
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1928ms
memory: 141124kb
input:
4446 21 23 21 21 20 19 10 6 11 9 21 18 9 14 1 18 11 14 2 19 15 17 11 6 2 19 17 3 16 1 7 5 11 17 4 10 20 13 16 13 3 13 8 9 11 12 13 12 18 12 3 13 4 10 11 6 1 14 9 15 21 8 19 18 5 16 17 7 20 2 24 28 24 19 15 2 11 20 18 19 17 8 6 3 10 21 18 22 6 21 10 14 6 14 7 5 19 2 23 5 10 1 11 12 20 13 16 24 3 10 9...
output:
12 19 8 4 5 2 15 12 12 18 13 13 4 6 10 11 7 13 15 12 11 0 5 0 11 10 3 0 12 1 15 15 12 11 11 7 13 7 15 12 8 14 4 6 12 11 0 17 18 16 1 1 15 11 6 10 12 18 11 3 2 11 9 12 0 5 16 3 11 15 11 14 12 14 0 15 12 16 9 14 15 10 1 18 11 4 3 0 8 11 11 11 19 16 12 13 19 0 7 11 15 5 14 0 14 4 13 2 8 12 12 0 17 16 1...
result:
ok 4446 lines