• BZOJ 1179 [Apio2009]Atm


    题解:裸的缩点+最短路(DP)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int maxn=500009;
    const int oo=1000000000;
    
    int n,m;
    int v[maxn];
    
    int cntedge;
    int head[maxn];
    int to[maxn<<1],nex[maxn<<1];
    void Addedge(int x,int y){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	head[x]=cntedge;
    }
    
    vector<int>G[maxn];
    int dfsclock,scccnt;
    int pre[maxn],lowlink[maxn],sccno[maxn];
    int S[maxn],top;
    void Dfs(int u){
    	pre[u]=lowlink[u]=++dfsclock;
    	S[++top]=u;
    	
    	for(int i=0;i<G[u].size();++i){
    		int v=G[u][i];
    		if(!pre[v]){
    			Dfs(v);
    			lowlink[u]=min(lowlink[u],lowlink[v]);
    		}else if(!sccno[v]){
    			lowlink[u]=min(lowlink[u],pre[v]);
    		}
    	}
    	
    	if(lowlink[u]==pre[u]){
    		++scccnt;
    		for(;;){
    			int x=S[top--];
    			sccno[x]=scccnt;
    			if(x==u)break;
    		}
    	}
    }
    
    int isb[maxn];
    int w[maxn];
    void Tarjan(){
    	for(int i=1;i<=n;++i){
    		if(!pre[i])Dfs(i);
    	}
    	for(int i=1;i<=n;++i)w[sccno[i]]+=v[i];
    	for(int u=1;u<=n;++u){
    		for(int i=0;i<G[u].size();++i){
    			int v=G[u][i];
    			if(sccno[u]!=sccno[v])Addedge(sccno[u],sccno[v]);
    		}
    	}
    }
    int s;
    queue<int>q;
    int inq[maxn];
    int d[maxn];
    void Spfa(){
    	for(int i=1;i<=scccnt;++i){
    		d[i]=-oo;inq[i]=0;
    	}
    	d[s]=w[s];inq[s]=1;q.push(s);
    	while(!q.empty()){
    		int x=q.front();q.pop();inq[x]=0;
    		for(int i=head[x];i;i=nex[i]){
    			if(d[x]+w[to[i]]>d[to[i]]){
    				d[to[i]]=d[x]+w[to[i]];
    				if(!inq[to[i]]){
    					inq[to[i]]=1;
    					q.push(to[i]);
    				}
    			}
    		}
    	}
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	while(m--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		G[x].push_back(y);
    	}
    	for(int i=1;i<=n;++i)scanf("%d",&v[i]);
    	Tarjan();
    	
    	scanf("%d%d",&s,&m);
    	while(m--){
    		int x;scanf("%d",&x);
    		isb[sccno[x]]=1;
    	}
    	s=sccno[s];
    	Spfa();
    	int ans=-oo;
    	for(int i=1;i<=scccnt;++i){
    		if(isb[i])ans=max(ans,d[i]);
    	}
    	
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    Android Packaging Problem
    Dedecms中{dede:type}标签支持调用父级栏目名称
    DeDecms远程写入漏洞webshell (dedecms漏洞)
    Dedecms 目标仿站的学习视频
    关于前端JS走马灯(marquee)总结
    浏览器端如何使用VConsole.js调试代码?
    Firefox中input元素,不能重新获取焦点函数focus()
    Centos7 systemctl添加自定义系统开机服务
    织梦cms 内容模型 option下拉框 value 分离
    wdcp如何添加反向代理功能
  • 原文地址:https://www.cnblogs.com/zzyer/p/8454335.html
Copyright © 2020-2023  润新知