仙人掌与圆方树(留坑)

先备个份:
check 有向图的仙人掌:

#include <bits/stdc++.h>
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 1e4 + 5;
vector<int> g[N];
bool vis[N];
int low[N], dfn[N], dcnt, n, m;
stack<int> st;
int scnt = 0;
bool Tarjan(int u){
    dfn[u] = low[u] = ++dcnt;
    st.push(u);
    vis[u] = true;
    int counter = 0;
    for(int v : g[u]){
        if(!dfn[v]){
            bool flag = Tarjan(v);
            if (!flag) return false;
            low[u] = min(low[u], low[v]);
            if (dfn[u] < low[v]) return false;
        	if (low[v] < dfn[u]) counter ++;
        }
        else {
        	if(!vis[v]) 
        		return false;
        	low[u] = min(low[u], dfn[v]);
        	counter ++;
		}
    }
//    if (counter > 1) {
//    	cout << "debug : counter limit " << u << " : " << counter << "\n";
//	}
    if (counter > 1) return false;
//    if (mx < low[u]) {
//    	cout << "debug : too big " << u << '\n';
//	}
    if(low[u] == dfn[u]){
    	scnt ++;
        while(true){
            int v = st.top();
            st.pop();
            vis[v] = false;
            if(u == v) break;
        }
    }
    return true;
}
void solve(void) {
	cin >> n >> m;
	for (int i = 0; i <= n; ++i) 
		g[i].clear();
	memset(low, 0, sizeof low);
	memset(dfn, 0, sizeof dfn);
	memset(vis, 0, sizeof vis);
	while (st.size()) st.pop();
	dcnt = 0;
	scnt = 0;
	for (int i = 1; i <= m; ++i) {
		int u, v; cin >> u >> v;
		g[u].push_back(v);
	}
	for (int i = 0; i < n; ++i)
		if (!dfn[i]) {
			if (!Tarjan(i)) {
				cout << "NO\n";
				return;
			}
		}
	if (scnt > 1) {
		cout << "NO\n";
		return;
	}
	else {
		cout << "YES\n";
	}
}
int main() {
	FASTIO;
	int t; cin >> t;
	while (t --)
		solve();
	return 0;
} 

无向图:

#include <bits/stdc++.h>
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 1e5 + 5;
vector<int> g[N];
int low[N], dfn[N], cnt[N], dcnt, n, m;
int fa[N];
bool flag = true;
int find(int x) {
	if (x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}
void dfs(int u, int fa) {
	if (!flag) return;
	low[u] = dfn[u] = ++dcnt;
	for(auto v : g[u]) {
		if(!dfn[v]) {
			dfs(v, u);
			if (!flag) return;
			low[u] = min(low[u], low[v]);
			if (low[v] < dfn[u])
				cnt[u] ++;
		}
		else if(v != fa) {
			low[u] = min(low[u], dfn[v]);
			if (dfn[v] < dfn[u]) 
				cnt[u] ++;
		}
	}
	if (cnt[u] > 1) {
		flag = false;
	}
}
void solve(void) {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
		g[i].clear();
	for (int i = 1; i <= n; ++i)
		fa[i] = i;
	memset(cnt, 0, sizeof cnt);
	memset(low, 0, sizeof low);
	memset(dfn, 0, sizeof dfn);
	dcnt = 0;
	flag = true;
	for (int i = 1; i <= m; ++i) {
		int u, v; cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
		int fu = find(u), fv = find(v);
		if (fu == fv) continue;
		fa[fu] = fv;
		cout << ":get : " << fu << " " << fv << '\n';
	}  
	int tmp = find(1);
	for (int i = 1; i <= n; ++i)
		if (find(i) != tmp) {
			cout << "NO\n";
			return;
		}
	dfs(1, 0);
	if (!flag) {
		cout << "NO\n";
	} 
	else {
		cout << "YES\n";
	}
}
int main() {
	FASTIO;
	int t; cin >> t;
	while (t --) {
		solve();
	}
	return 0;
}
posted @ 2025-05-27 21:17  tanjiaqi  阅读(6)  评论(0)    收藏  举报