• 【洛谷5008】逛庭院(Tarjan,贪心)


    【洛谷5008】逛庭院(Tarjan,贪心)

    题面

    洛谷

    题解

    如果图是一个(DAG),我们可以任意选择若干个不是入度为(0)的点,然后把它们按照拓扑序倒序删掉,不难证明这样一定是合法的。
    现在的问题是出现了(SCC),我们缩点之后(SCC)形成了一个(SCC),我们还是贪心考虑,显然不是入度为(0)(SCC)仍然可以类似上面的任意删点,只需要按照(SCC)的拓扑序倒序处理,对于入度为(0)(SCC),至少要留下一个点,那么这样子就可以判断了。

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define MAX 500500
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    vector<int> E[MAX];
    int dfn[MAX],low[MAX],tim,G[MAX],gr,sz[MAX],dg[MAX];
    int St[MAX],top;bool ins[MAX];
    void Tarjan(int u)
    {
    	dfn[u]=low[u]=++tim;St[++top]=u;ins[u]=true;
    	for(int v:E[u])
    		if(!dfn[v])Tarjan(v),low[u]=min(low[u],low[v]);
    		else if(ins[v])low[u]=min(low[u],dfn[v]);
    	if(dfn[u]==low[u])
    	{
    		int v;++gr;
    		do{v=St[top--];ins[v]=false;sz[G[v]=gr]++;}while(u!=v);
    	}
    }
    int n,m,K,ans,a[MAX],p[MAX];
    bool cmp(int x,int y){return a[x]>a[y];}
    int main()
    {
    	n=read();m=read();K=read();
    	for(int i=1;i<=n;++i)a[i]=read(),p[i]=i;
    	for(int i=1,u,v;i<=m;++i)u=read(),v=read(),E[u].push_back(v);
    	sort(&p[1],&p[n+1],cmp);
    	for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(i);
    	for(int i=1;i<=n;++i)
    		for(int v:E[i])
    			if(G[v]!=G[i])dg[G[v]]++;
    	for(int i=1;i<=gr;++i)sz[i]+=dg[i];
    	for(int i=1;i<=n&&K;++i)
    	{
    		int u=p[i];
    		if(sz[G[u]]>1)ans+=a[u],--sz[G[u]],--K;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    解决word启动时报找不到mathpage.wll错误
    单应性(homography)变换的推导
    深度残差网(deep residual networks)的训练过程
    《OpenCV3 计算机视觉--Python语言实现 第二版》源代码及纠错
    jquery版结婚电子请帖
    jquery版小型婚礼(可动态添加祝福语)
    OOP感想
    前端笔试题解答
    jquery版瀑布流
    jquery版时钟(css3实现)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/11151571.html
Copyright © 2020-2023  润新知