44pts 求调,帮助必关
查看原帖
44pts 求调,帮助必关
656427
iamsh楼主2025/7/22 11:44

除了 #2,#5,#8,#11 和 #12 都错了,思路是先用 Tarjan 缩成 DAG 再用拓扑排序求范围

// Code by iamsh

#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
int n,m,A,B,x[N],y[N];
int dfn[N],tot,low[N],scc[N];
bool instk[N];
int stk[N],top;
vector<int> g[N],G[N];
int in[N],cnt;
map<int,int> mp;
pair<int,int> dp[N];
vector<int> tpn;
queue<int> q;
vector<pair<int,int>> ans;
void gmin(int &a,int b) {
	a = a < b ? a : b;
}
void gmax(int &a,int b) {
	a = a > b ? a : b;
}
void tarjan(int u) {
	low[u] = dfn[u] = ++ tot;
	stk[++ top] = u,instk[u] = 1;
	for(int v : g[u]) {
		if(!dfn[v]) {
			tarjan(v);
			gmin(low[u],low[v]);
		} 
		if(instk[v]) {
			gmin(low[u],dfn[v]);
		}
	}
	if(dfn[u] == low[u]) {
		int v;
		do {
			v = stk[top --];
			scc[v] = u,instk[v] = 0;
		} while(v != u);
	}
}
void solve() {
	cin >> n >> m >> A >> B;
	for(int i = 1;i <= n;i ++) {
		cin >> x[i] >> y[i];
		if(x[i] == A) {
			mp[y[i]];
		}
	}
	for(auto &x : mp) {
		x.second = ++ cnt;
	}
	while(m --) {
		int u,v,d;
		cin >> u >> v >> d;
		g[u].push_back(v);
		if(d != 1) {
			g[v].push_back(u);
		}
	}
	for(int i = 1;i <= n;i ++) {
		if(!dfn[i]) {
			tarjan(i);
		}
	}
	for(int u = 1;u <= n;u ++) {
		for(int v : g[u]) {
			if(scc[u] != scc[v]) {
				G[scc[u]].push_back(scc[v]);
			}
		}
	}
	for(int u = 1;u <= n;u ++) {
		sort(G[u].begin(),G[u].begin());
		G[u].erase(unique(G[u].begin(),G[u].end()),G[u].end());
		for(int v : G[u]) {
			in[v] ++;
		}
	}
    for(int i = 1;i <= n;i ++) {
        dp[i] = {B + 1,-1};
    }
    for(int i = 1;i <= n;i ++) {
        if(x[i] == A) {
            gmin(dp[scc[i]].first,y[i]);
            gmax(dp[scc[i]].second,y[i]);
        }
    }
    for(int i = 1;i <= n;i ++) {
        if(scc[i] == i && !in[i]) {
            q.push(i);
        }
    }
    while(q.size()) {
        int u = q.front();
        q.pop();
        tpn.push_back(u);
        for(int v : G[u]) {
            if(!(-- in[v])) {
                q.push(v);
            }
        }
    }
    for(int i = tpn.size() - 1;~i;i --) {
        int u = tpn[i];
        for(int v : G[u]) {
            gmin(dp[u].first,dp[v].first);
            gmax(dp[u].second,dp[v].second);
        }
    }
    for(int i = 1;i <= n;i ++) {
        if(x[i] == 0) {
            if(dp[scc[i]].second < 0) {
            	ans.push_back({y[i],0});
            	continue;
            }
            int l = mp[dp[scc[i]].first];
            int r = mp[dp[scc[i]].second];
            ans.push_back({y[i],r - l + 1});
        }
    }
	sort(ans.begin(),ans.end(),greater<pair<int,int>>());
	for(auto x : ans) {
		cout << x.second << "\n";
	}
}
int main() {
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cout << fixed << setprecision(12);
	int t = 1;
//	cin >> t;
	while(t --) {
		solve();
	}
	return 0;
}
2025/7/22 11:44
加载中...