2 solutions

  • 4
    @ 2025-7-2 9:49:55

    HYR要求的对拍

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int MAXN=500001;
    vector<int>edge[MAXN];
    int instk[MAXN],dfn[MAXN],ss[MAXN],sa[MAXN],low[MAXN],belong[MAXN],pt[MAXN],mem[MAXN],tot,stknum,ans,n,m;
    //sa:强连通点权
    //mem:每个点的最大权值和
    vector<int>g[MAXN];
    stack<int>stk;
    void tarjan(int x){
    	dfn[x]=low[x]=++tot,instk[x]=1;
    	stk.push(x);
    	for(int i:edge[x]){
    		if(!dfn[i]){
    			tarjan(i);
    			low[x]=min(low[x],low[i]);
    		}else if(instk[i]){
    			low[x]=min(low[x],dfn[i]);
    		}
    	}
    	if(dfn[x]==low[x]){
    		int y;
    		stknum++;
    		do{
    			y=stk.top();
    			stk.pop();
    			ss[stknum]++;
    			instk[y]=0;
    			belong[y]=stknum;
    			sa[stknum]+=pt[y];
    			for(int v:edge[y])mem[stknum]=max(mem[stknum],mem[belong[v]]);
    		}while(y!=x);
    		mem[stknum]+=sa[stknum];
    		ans=max(ans,mem[stknum]);
    	}
    }
    signed main(){
    //	freopen("P.in","r",stdin);
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)cin>>pt[i];
    	for(int i=1;i<=m;i++){
    		int u,v;
    		cin>>u>>v;
    		edge[u].emplace_back(v);
    	}
    	for(int i=1;i<=n;i++){
    		if(!dfn[i])tarjan(i);
    	}
    	cout<<ans;
    }
    

    @开心了吧

    • 1
      @ 2025-7-2 20:39:35

      在普通的 tarjan 上进行缩点,不过我用的是新建图。

      #include <bits/stdc++.h>
      using namespace std;
      typedef long long ll;
      const int N = 1e4 + 5,M = 1e5 + 5;
      int n,m,tot,dfn[N],low[N],cnt,f[N],a[N],a2[N],dp[N],mx;
      bool is[N],f2[N];
      vector<int> g[N],root,g2[N];
      void dfs(int u){
      	dfn[u] = ++tot,low[u] = dfn[u];
      	for (int v : g[u]){
      		if (!dfn[v])	dfs(v);
      	}
      }
      stack<int> s;
      void tarjan(int u){
      	s.push(u);
      	f[u] = 1;
      	is[u] = 1;
      	for (int v : g[u]){
      		if (!f[v])	tarjan(v);
      		if (is[v])	low[u] = min(low[u],low[v]);
      	}
      	if (dfn[u] == low[u]){
      		cnt++;
      		int sum = a[u];
      		f[u] = cnt;
      		while (s.top() != u){
      			sum += a[s.top()];
      			f[s.top()] = cnt;
      			is[s.top()] = 0;
      			s.pop();
      		}
      		a2[cnt] = sum;
      		s.pop();
      		is[u] = 0;
      	}
      }
      int dps(int u){
      	f2[u] = 1;
      	dp[u] = a2[u];
      	for (int v : g2[u]){
      		if (!f2[u])	dps(v);
      		dp[u] = max(dp[u],dp[v] + a2[u]);
      	}
      	return dp[u];
      }
      int main(int argc, char **argv){
      	cin >> n >> m;
      	for (int i = 1;i <= n;i++)	cin >> a[i];
      	for (int i = 1;i <= m;i++){
      		int u,v;
      		cin >> u >> v;
      		g[u].push_back(v);
      	}
      	for (int i = 1;i <= n;i++){
      		if (!dfn[i])	dfs(i),root.push_back(i);
      	}
      	for (int i : root)	tarjan(i);
      	for (int i = 1;i <= n;i++){
      		for (int v : g[i]){
      			if (f[i] != f[v])	g2[f[i]].push_back(f[v]);
      		}
      	}
      	for (int i = 1;i <= cnt;i++){
      		if (!f2[i])	mx = max(mx,dps(i));
      	}
      	cout << mx;
      	return 0;
      }
      
      • 1

      Information

      ID
      417
      Time
      1000ms
      Memory
      512MiB
      Difficulty
      7
      Tags
      # Submissions
      49
      Accepted
      13
      Uploaded By