zoukankan      html  css  js  c++  java
  • 894E

    想出正解之后感觉不太会缩点,今天学了一下tarjan,发现就是遍历边。。tarjan只是过程,存反向边dfs两次分解scc也能做

    #include<bits/stdc++.h>  
    //#pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>  
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip>  
    using namespace std;  
    #define ll long long  
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++) 
    #define sqr(a) (a)*(a)
    
    const int maxn=1e6+7;
    
    int n,m,st;
    ll psum[maxn];
    
    ll calc(ll x){
    	ll i=sqrt(2*x);
    	while(i*(i+1)<2*x)i++;
    	return i*x-(i*(i+1)*(i-1)/6);
    }
    
    ll dp[maxn];
    
    struct EDGE{
    	int from,to,d,nxt;
    	bool sign;	//桥
    }edge[maxn<<1];
    int head[maxn],edgenum;
    void add(int u,int v,int d){
    	edge[edgenum]=(EDGE){u,v,d,head[u]};head[u]=edgenum++;
    }
    int DFN[maxn],Low[maxn],Stack[maxn],top,Time;
    //Low[u]是u的子树反向弧能指向的最靠近总根的祖先的时间戳
    int taj;
    int Belong[maxn];	//连通分量所属
    bool Instack[maxn];
    vector<int>bcc[maxn];
    
    void tarjan(int u,int fa){
    	DFN[u]=Low[u]=++Time;
    	Stack[top++]=u;
    	Instack[u]=1;
    	for(int i=head[u];~i;i=edge[i].nxt){
    		int v=edge[i].to;
    		if(DFN[v]==-1){
    			tarjan(v,u);
    			Low[u]=min(Low[u],Low[v]);
    			if(DFN[u]<Low[v]){		//v上不去
    				edge[i].sign=1;
    			}
    		}else if(Instack[v])Low[u]=min(Low[u],DFN[v]);
    	}
    	if(Low[u]==DFN[u]){
    		int now;
    		taj++;bcc[taj].clear();
    		do{
    			now=Stack[--top];
    			Instack[now]=0;
    			Belong[now]=taj;
    			bcc[taj].pb(now);
    		}while(now!=u);
    	}
    }
    void tarjan_init(int all){
    	memset(DFN,-1,sizeof DFN);
    	memset(Instack,0,sizeof Instack);
    	top=Time=taj=0;
    	for(int i=1;i<=all;i++)if(DFN[i]==-1)tarjan(i,i);
    }
    struct NODE{
    	int v;
    	int d;
    };
    vector<NODE>G[maxn];
    int du[maxn];
    void suodian(){
    	memset(du,0,sizeof du);
    	for(int i=1;i<=taj;i++)G[i].clear();
    	for(int i=0;i<edgenum;i++){
    		int u=Belong[edge[i].from],v=Belong[edge[i].to];
    		if(u!=v){
    			G[u].pb((NODE){v,edge[i].d});du[v]++;
    		}
    		else{psum[u]+=calc(edge[i].d);}
    	}
    }
    void init(){memset(head,-1,sizeof head);}
    
    int vis[maxn];
    void dfs(int u){
    	vis[u]=1;dp[u]=0;
    	for(int i=0;i<G[u].size();i++){
    		if(!vis[G[u][i].v])dfs(G[u][i].v);
    		dp[u]=max(dp[u],dp[G[u][i].v]+G[u][i].d);
    	}
    	dp[u]+=psum[u];
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	init();
    	FOR(m){
    		int u,v,w;scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w);
    	}
    	scanf("%d",&st);
    	tarjan_init(n);
    	suodian();
    	dp[Belong[st]]=psum[Belong[st]];
    	dfs(Belong[st]);
    	printf("%lld
    ",dp[Belong[st]]);
    }


  • 相关阅读:
    androidactivity与webview结合
    anroid打包
    android之Fragment
    android布局
    anroid
    map reduce filter
    杂记
    spark记录
    Tomact和XML配置文件
    js-day02
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611204.html
Copyright © 2011-2022 走看看