WA 18pts 求助
查看原帖
WA 18pts 求助
453555
qW__Wp楼主2024/4/11 22:08

只 A 了 #1 #4

#include <bits/stdc++.h>
//#define int long long
#define INF 0x3fffffff
#define INFF 9e19

using namespace std;

const int N = 1e4 + 5;

int hd[N], cnt = 1;
int dfn[N], low[N], times, st[N], tot, top, color[N], d[N];
int x[N], y[N];
bool vis[N << 1], vis2[N];

struct Edge {
	int to, nx;
} e[N << 1];

void add(int u, int v) {
	e[ ++ cnt] = {v, hd[u]}, hd[u] = cnt;
}

void tarjan(int u) {
	dfn[u] = low[u] = ++ times;
	st[ ++ top] = u;
	vis2[u] = 1;
	for (int i = hd[u]; i; i = e[i].nx) {
		int v = e[i].to;
		if (vis[i]) continue;
		vis[i] = vis[i ^ 1] = true;
		if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
		else if (vis2[v]) low[u] = min(low[u], dfn[v]);
	}
	if (dfn[u] == low[u]) {
		tot ++;
		while (1) {
			int v = st[top -- ];
			color[v] = tot;
			vis2[v] = 0;
			if (v == u) break;
		}
	}
}

signed main() {
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m; i ++) {
		cin >> x[i] >> y[i];
		add(x[i], y[i]), add(y[i], x[i]);
	} 
	for (int i = 1; i <= n; i ++) if (!dfn[i]) top = 0, tarjan(i);
//	cout << tot << endl;
//	for (int i = 1; i <= n; i ++) cout << color[i] << ' ';
//	cout << endl;
	for (int i = 1; i <= m; i ++) {
		int u = color[x[i]], v = color[y[i]];
		if (u != v) d[u] ++, d[v] ++;
	}
	int ans = 0;
	for (int i = 1; i <= n; i ++) if (d[i] == 0) ans ++;
	cout << (ans + 1) / 2;
	return 0;
}

发现我和 https://www.luogu.com.cn/discuss/616286 的 lz 写法差不多,于是尽量还原了 ta 的正确做法,但还是 18pts

ta 的错误解法只 A 了 #7 #9,但我的 只 A 了 #1 #4

放上那位佬的代码

#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <climits>
#include <queue>
#include <stack>

#define endl "\n"
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
//#define int long long
#define ULL unsigned long long
#define ls(k) k << 1
#define rs(k) k << 1 | 1	
#define mid(a, b) (a + b) >> 1 

const int N = 5e3 + 6, M = 1e4 + 5;

using namespace std;

inline int read(){
    int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
	while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
	return x * f;
} 

int n, m;

int h[N], edges; // ta 是把edges赋初值为1就过了

struct node

{
	int nx, to;	
}e[M * 2];

int st[N], top, low[N], num[N], dfn, res, ans;

int u[N], v[N], color[N], degree[N];

bool vis[M * 2], insta[N];	

void add(int u, int v)

{
	edges ++;
	e[edges].nx = h[u], e[edges].to = v, h[u] = edges;
	edges ++;
	e[edges].nx = h[v], e[edges].to = u, h[v] = edges;
}

void tarjan(int u)

{
	low[u] = num[u] = ++ dfn;
	st[++ top] = u, insta[u] = true;
	for (int i = h[u]; i; i = e[i].nx)
	{
		if (vis[i]) continue; 
		vis[i] = vis[i ^ 1] = true;
		int j = e[i].to;
		if (!num[j]) tarjan(j), low[u] = min(low[u], low[j]);
		else if (insta[j]) low[u] = min(low[u], num[j]);
	}
	if (num[u] == low[u])
	{
		color[u] = ++ res;
		insta[u] = false;
		while (st[top] != u) color[st[top]] = res, insta[st[top]] = false, top --;
		top --;
	}
}

signed main()

{
	//IOS;
	
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i ++ ) 
	{
		scanf("%d%d", &u[i], &v[i]);
		add(u[i], v[i]);	
	}
	for (int i = 1; i <= n; i ++ )
	{
		if (!num[i]) tarjan(i);
	}
	for (int i = 1; i <= m; i ++ )
	{
		if (color[u[i]] != color[v[i]]) degree[color[u[i]]] ++, degree[color[v[i]]] ++;
	}	
	for (int i = 1; i <= res; i ++ )
		if (degree[i] == 1) ans ++;
	//cout << ans << endl;
	printf("%d", (ans + 1) / 2);
}

ta 的代码把 31 行 edge 初值赋值为 1 就过了

感激不尽!

2024/4/11 22:08
加载中...