• 【题解】CF894E Ralph and Mushrooms (缩点)


    【题解】CF894E Ralph and Mushrooms (缩点)

    这是紫?给个解方程算法

    考虑一条边若可以重复遍历说明一定有环,有环的话一定会把环上的蘑菇榨干,考虑一条边从全部到榨干的贡献是多少

    [sum_{i=0}^x (w-sum_{j=0}^i j)=sum_{i=0}^x (w-{i(i+1)over 2}) ]

    那么考虑解出(x)的值,根据初中知识解出来(x=lfloor{-1+sqrt{1+8w}over 2} floor),预处理(sum {i(i+1)over 2})可以直接计算贡献(其实也可以解通项公式)

    然后Tarjan缩点之后变成DAG上的DP,同时有点权和边权的DAG DP

    时间复杂度(O(n))

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    
    using namespace std;  typedef long long ll;   char __buf[1<<18],*__c=__buf,*__ed=__buf;
    inline int qr(){
    	register int ret=0,f=0;
    	register char c=getchar();
    	while(!isdigit(c))f|=c==45,c=getchar();
    	while(isdigit(c)) ret=ret*10+c-48,c=getchar();
    	return f?-ret:ret;
    }
    
    const int maxn=1e6+5;
    struct E{int to,w;};
    vector<E> e[maxn],e2[maxn];
    inline void add(const int&fr,const int&to,const int&w){e[fr].push_back({to,w});}
    inline void add2(const int&fr,const int&to,const int&w){
    	e2[fr].push_back({to,w});
    }
    int n,m;
    int qaq[maxn],cnt;
    ll w[maxn],dp[maxn];
    bool usd[maxn];
    int low[maxn],dfn[maxn],in[maxn],stk[maxn],top,siz[maxn];
    ll s[maxn];
     
    void dfs(const int&now){
    	stk[++top]=now; in[now]=1;
    	low[now]=dfn[now]=++*dfn;
    	for(auto t:e[now]){
    		if(!dfn[t.to]) dfs(t.to),low[now]=min(low[now],low[t.to]);
    		else if(in[t.to]) low[now]=min(dfn[t.to],low[now]);
    	}
    	if(low[now]==dfn[now]){
    		++cnt;
    		int temp;
    		do temp=stk[top--],in[temp]=0,qaq[temp]=cnt,++siz[cnt];
    		while(temp!=now);
    	}
    }
    
    ll Dp(const int&now){
    	if(usd[now]) return dp[now];
    	dp[now]=0;
    	for(auto t:e2[now]) dp[now]=max(dp[now],Dp(t.to)+t.w);
    	usd[now]=1;
    	return dp[now]=w[now]+dp[now];
    }
    
    int main(){
    	n=qr(); m=qr();
    	for(int t=1,t1,t2,t3;t<=m;++t) t1=qr(),t2=qr(),t3=qr(),add(t1,t2,t3);
    	for(int t=1;t<maxn;++t) s[t]=s[t-1]+(1ll*t*(t+1)>>1);
    	int S=qr();
    	dfs(S);
    	for(int t=1;t<=n;++t)
    		for(auto i:e[t]){
    			if(qaq[t]==qaq[i.to]) {
    				int k=(sqrt((long double)1+8ll*i.w)-1)/2.0;
    				w[qaq[t]]=w[qaq[t]]+(k+1ll)*i.w-s[k];
    			}
    			else add2(qaq[t],qaq[i.to],i.w);
    		}
    	ll ans=Dp(qaq[S]);
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
    
    
  • 相关阅读:
    1059. Prime Factors (25)
    mybatis中resultType和resultMap的区别
    Spring Boot中使用Swagger2构建强大的RESTful API文档
    ES6之6种遍历对象属性的方法
    QQ授权登录
    nodejs爬虫入门
    nrm -- NPM registry 管理工具(附带测速功能)
    Sublime Text 3 使用MarkDown编写带预览的文本
    js中字符串函数indexOf与search的区别
    linux基础入门
  • 原文地址:https://www.cnblogs.com/winlere/p/11807470.html
Copyright © 2020-2023  润新知