zoukankan      html  css  js  c++  java
  • 洛谷P3119草鉴定

    题目

    草鉴定,tarjan可以用来缩点,优化spfa的时间,

    缩点之后就是一个(DAG)了,因此完全可以用来跑spfa上的最长路,然后枚举每条边,查看是否这条边的两个节点分别可以到达起点所在的强连通分量。(因为要返回到1点)。然后更新答案就可以了。

    可是为什么要缩点呢,因为只能逆行一次,逆行之后通过在强连通分量上的点可以把强连通分量上的所有点全都遍历一次,最后还可以回到强连通分量上的起点,所以可以tarjan缩点。

    #include <bits/stdc++.h>
    using namespace std;
    int n, m, lin[100010], lne[100100], lf[101000], dfn[100010], low[100100], vis[100100], belong[100100], dis[1001000], dis2[101000], color, tot, cnt, ans, cntne, cntf;
    stack <int> s; 
    int sum[100100];struct edg {
    	int to, nex;
    }e[1000100], f[1000100], ne[100100];
    inline void add(int u, int v)
    {				
    	e[++cnt].to = v;
    	e[cnt].nex = lin[u];
    	lin[u] = cnt;
    }				
    inline void add2(int u, int v)
    {
    	ne[++cntne].to = v;
    	ne[cntne].nex = lne[u];
    	lne[u] = cntne;
    }
    inline void addf(int u, int v)
    {
    	f[++cntf].to = v;
    	f[cntf].nex = lf[u];
    	lf[u] = cntf;
    }
    inline void tarjan(int u)
    {				
    	dfn[u] = low[u] = ++tot;
        s.push(u); vis[u] = 1;
        for(int i = lin[u]; i; i = e[i].nex)
        {			
            int v = e[i].to;
            if(!dfn[v]) {		
                tarjan(v);
                low[u] = min(low[u],low[v]);
            }		
            else if(vis[v]) low[u] = min(low[u],dfn[v]);
        }			
        if(low[u] == dfn[u])
        {
            int v = -3;
            color++;
            do
            {
                v = s.top(); s.pop();
                belong[v] = color;
                vis[v] = 0;
                sum[color]++;
            } while (u != v);
        }
    }
    int inq[101000]; 
    inline void spfa()
    {
    	memset(dis, -123, sizeof(dis));
    	queue <int> q;
    	dis[belong[1]] = sum[belong[1]];
    	q.push(belong[1]);
    	while (!q.empty())
    	{	
    		int cur = q.front(); q.pop(); inq[cur] = 0;
    		for (int i = lne[cur]; i; i = ne[i].nex)
    		{
    			int to = ne[i].to;
    			if (dis[cur] + sum[to] > dis[to])
    			{
    				dis[to] = dis[cur] + sum[to];
    				if (!inq[to])
    					inq[to] = 1, q.push(to);
    			}
    		}
    	}
    }
    inline void sf()
    {	
    	memset(dis2, -123, sizeof(dis2));
    	queue <int> q;
    //	memset(vis, 0, sizeof(vis));
    	dis2[belong[1]] = sum[belong[1]];
    
    	q.push(belong[1]);
    	while (!q.empty())
    	{
    		int cur = q.front(); q.pop(); inq[cur] = 0;
    		for (int i = lf[cur]; i; i = f[i].nex)
    		{
    			int to = f[i].to;
    			if(dis2[cur] + sum[to] > dis2[to])
    			{
    				dis2[to] = dis2[cur] + sum[to];
    				if (!inq[to])
    					inq[to] = 1, q.push(to);
    			}
    		}
    	}
    }	
    int b1[100100], b2[101000];
    void dfs1(int u)
    {
    	b1[u] = 1;
    	for (int i = lne[u]; i; i = ne[i].nex)
    		if (!b1[ne[i].to])
    			dfs1(ne[i].to);
    }
    void dfs2(int u)
    {
    	b2[u] = 1;
    	for (int i = lf[u]; i; i = f[i].nex)
    		if (!b2[f[i].to])
    			dfs2(f[i].to);
    }
    inline void init()
    {	
    	scanf("%d%d", &n, &m);
    	for (int i = 1, u, v; i <= m; i++)
    		scanf("%d%d", &u, &v), add(u, v);
    	for (int i = 1; i <= n; i++)
    		if (!dfn[i]) tarjan(i);
    		
    }
    inline void jiantu()
    {	
    	for (int i = 1; i <= n; i++)
    		for (int j = lin[i]; j; j = e[j].nex)
    		{
    			int to = e[j].to;
    			if (belong[i] != belong[to]) add2(belong[i], belong[to]), addf(belong[to], belong[i]);	
    		}
    }
    int main()
    {
    	init();	
    	jiantu();
    	dfs1(belong[1]);
    	dfs2(belong[1]);
    	spfa();
    	sf();				  
    	for (int i = 1; i <= color; i++)
    		if (b1[i])		  
    			for (int j = lf[i]; j; j = f[j].nex)
    				if (b2[f[j].to])
    					ans = max(ans, dis2[f[j].to] + dis[i]);
    	ans -= sum[belong[1]];
    	printf("%d
    ", ans);	  
    	return 0;
    }
    
  • 相关阅读:
    CentOS 6.3下部署LVS(NAT)+keepalived实现高性能高可用负载均衡
    三大WEB服务器对比分析(apache ,lighttpd,nginx)
    linux sudo 命令
    linux 添加用户、权限
    LeetCode——Find Largest Value in Each Tree Row
    LeetCode——Single Element in a Sorted Array
    LeetCode——Find All Duplicates in an Array
    LeetCode—— Partition Equal Subset Sum
    LeetCode——Unique Binary Search Trees II
    LeetCode——Is Subsequence
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/10850098.html
Copyright © 2011-2022 走看看