QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#193466#6861. Counter StrikesususyAC ✓1928ms141124kbC++145.4kb2023-09-30 17:13:232023-09-30 17:13:24

Judging History

你现在查看的是最新测评结果

  • [2023-09-30 17:13:24]
  • 评测
  • 测评结果:AC
  • 用时:1928ms
  • 内存:141124kb
  • [2023-09-30 17:13:23]
  • 提交

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