zoukankan      html  css  js  c++  java
  • 绵阳东辰国际test201909.29

    爆零场!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    说说我的心路历程:

    n个点,m条双向边---->缩点?

    颜色只有三种,最大值-------->dp?

    然后就搞来搞去就没搞出来

    solution:

    预处理每个点在每种颜色下处于那个联通块

    对每种颜色分别建图Tarjan缩点

    假如询问点为x,此时的颜色为t

    则在此时颜色t的图中可以走到的(也就是它所处的强连通分量),就都可走(过程又不用花费)

    考虑要变颜色的路径可能会与以前的颜色路径重复,怎么办?容斥减掉就好

    这里就可以用map维护

    最后分情况对于每个点取个最大的就好

    code by chitongzi

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 100000 + 5, M = 200000 + 5;
    inline void read(int&a)
    {
    	a = 0; char k = getchar (); int f = 1;
    	while (k > '9' || k < '0') { if (k == '-') f = -1; k = getchar (); }
    	while (k >= '0' && k <= '9') { a = a * 10 + k - '0'; k = getchar (); }
    	a *= f;
    }
    int c[N];
    struct Graph {
    	int fr[M << 1], to[M << 1], h[N], tot;
    	int stk[N], top, dfn[N], low[N], dftot, color[N], cocnt, ans[N];
    	int sumc[N];
    	bool ins[N];
    	inline void adde (int u, int v)
    	{
    		tot++;
    		fr[tot] = h[u];
    		to[tot] = v;
    		h[u] = tot;
    	}
    	inline void tarjan (int p)
    	{
    		dfn[p] = ++dftot;
    		ins[p] = 1;
    		stk[++top] = p;
    		low[p] = dfn[p];
    		for (int i = h[p]; i; i = fr[i])
    		{
    			if (!dfn[ to[i] ])
    			{
    				tarjan ( to[i] );
    				low[p] = min (low[p], low[ to[i] ]);
    			}
    			else if (ins[ to[i] ])
    				low[p] = min (low[p], dfn[ to[i] ]);
    		}
    		if (low[p] == dfn[p])
    		{
    			bool flag = true;
    			++cocnt;
    			while (flag)
    			{
    				if (stk[top] == p) flag = false;
    				color[ stk[top] ] = cocnt;
    				sumc[cocnt] += c[ stk[top] ];
    				ins[ stk[top] ] = 0;
    				--top;
    			}
    		}
    	}
    }g[4];
    map<pair<int, int>, int> mp[3];
    int n, m;
    signed main ()
    {
    	freopen ("grape.in", "r", stdin);
    	freopen ("grape.out", "w", stdout);
    	read(n), read(m);
    	for (int i = 1; i <= n; ++i)read (c[i]);
    	for (int i = 1, x, y, z; i <= m; ++i)
    	{
    		read (x), read (y), read (z);
    		for (int k = 1; k <= 3; ++k)
    			if (k != z)
    				g[k].adde (x, y), g[k].adde (y, x);
    	}
    	for (int k = 1; k <= 3; ++k)
    		for (int i = 1; i <= n; ++i)
    			if (!g[k].dfn[i])
    				g[k].tarjan (i);
    	for (int i=1; i <= n; ++i)
    	{
    		int idx = g[1].color[i], idy = g[2].color[i], idz = g[3].color[i];
    		mp[0][ make_pair (idx, idy) ] += c[i];
    		mp[1][ make_pair (idy, idz) ] += c[i];
    		mp[2][ make_pair (idx, idz) ] += c[i];
    	}
    	for (int i = 1; i <= n; ++i)
    	{
    		int idx = g[1].color[i], idy = g[2].color[i], idz = g[3].color[i];
    		g[1].ans[idx]=max(g[1].ans[idx],g[1].sumc[idx]+g[2].sumc[idy]-mp[0][make_pair(idx,idy)]);
    		g[1].ans[idx]=max(g[1].ans[idx],g[1].sumc[idx]+g[3].sumc[idz]-mp[2][make_pair(idx,idz)]);
    		g[2].ans[idy]=max(g[2].ans[idy],g[2].sumc[idy]+g[1].sumc[idx]-mp[0][make_pair(idx,idy)]);
    		g[2].ans[idy]=max(g[2].ans[idy],g[2].sumc[idy]+g[3].sumc[idz]-mp[1][make_pair(idy,idz)]);
    		g[3].ans[idz]=max(g[3].ans[idz],g[3].sumc[idz]+g[1].sumc[idx]-mp[2][make_pair(idx,idz)]);
    		g[3].ans[idz]=max(g[3].ans[idz],g[3].sumc[idz]+g[2].sumc[idy]-mp[1][make_pair(idy,idz)]);
    	}
    	int q;
    	read (q);
    	for (int i = 1; i <= q; ++i)
    	{
    		int tmp; read (tmp);
    		int idx = g[1].color[tmp], idy = g[2].color[tmp], idz = g[3].color[tmp];
    		printf ("%lld
    ", max (g[1].ans[ idx ], max (g[2].ans[ idy ], g[3].ans[ idz ])));
    	}
    	return 0;
    }
    

  • 相关阅读:
    TCP/IP协议栈概述及各层包头分析
    Maven:Non-resolvable parent POM: Failure to find错误
    mysql alter 用法,修改表,字段等信息
    PowerDesigner16 设置导出sql文件的编码
    linux iptables开放/关闭端口命令
    Enterprise Architect 13 : 需求建模 自动命名并计数
    Enterprise Architect 13 : 将绘制的图形导出成图片 或者 拷贝到剪贴板中
    Enterprise Architect 13 : 设置默认代码环境
    使用MyBatis查询 返回类型为int,但是当查询结果为空NULL,报异常的解决方法
    PowerDesigner16 修改表或表的字段Name的时候不让Code不自动跟着变
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11608359.html
Copyright © 2011-2022 走看看