社区讨论

60pts 求调

P10935银河参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mhj9805x
此快照首次捕获于
2025/11/03 22:47
4 个月前
此快照最后确认于
2025/11/03 22:47
4 个月前
查看原帖
Code:
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct Node{
	int v,w;
};
int n,m,idx,cnt;
ll ans;
int dfn[N],low[N],s[N],c[N],ind[N];
ll dp[N];
vector<Node> g[N],e[N];
bitset<N> vis;
stack<int> st;
void tarjan(int u){
	dfn[u]=low[u]=++idx;
	st.push(u);
	vis[u]=1;
	for (const auto &i:g[u]){
		int v=i.v;
		if (!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}else if (vis[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if (dfn[u]==low[u]){
		cnt++;
		while (st.top()!=u){
			int x=st.top();
			st.pop();
			s[x]=cnt;
			//cerr<<cnt<<","<<x<<"\n";
			c[cnt]++;
			vis[x]=0;
		}
		int x=st.top();
		st.pop();
		s[x]=cnt;
		//cerr<<cnt<<","<<x<<"\n";
		c[cnt]++;
		vis[x]=0;
	}
}
void topo(){
	queue<int> q;
	for (int i=1;i<=cnt;i++)if (!ind[i])q.push(i),dp[i]=1;
	while (!q.empty()){
		int u=q.front();
		q.pop();
		for (const auto &i:e[u]){
			int v=i.v,w=i.w;
			dp[v]=max(dp[v],dp[u]+w);
			ind[v]--;
			if (!ind[v])q.push(v);
		}
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for (int i=1;i<=m;i++){
		int t,u,v;
		cin>>t>>u>>v;
		if (t==1)g[u].push_back({v,0}),g[v].push_back({u,0});
		else if (t==2)g[u].push_back({v,1});
		else if (t==3)g[u].push_back({v,0});
		else if (t==4)g[v].push_back({u,1});
		else if (t==5)g[v].push_back({u,0});
	}
	/*for (int i=1;i<=n;i++){
		if (g[i].size())for (const auto &j:g[i]){
			cerr<<i<<"->"<<j.v<<","<<j.w<<"\n";
		}
	}*/
	for (int i=1;i<=n;i++)if (!dfn[i])tarjan(i);
	for (int i=1;i<=n;i++){
		for (const auto &j:g[i]){
			int v=j.v,w=j.w;
			if (s[i]!=s[v]){
				e[s[i]].push_back({s[v],w});
				ind[s[v]]++;
			}else{
				if (w)return cout<<-1,0;
			}
		}
	}
	topo();
	for (int i=1;i<=cnt;i++){
		ans+=c[i]*dp[i];
	}
	cout<<ans;
	return 0;
}
测了几个 corner case 都没问题,求调

回复

4 条回复,欢迎继续交流。

正在加载回复...