zoukankan      html  css  js  c++  java
  • 【YBTOJ】【Luogu P4180】[BJWC2010]严格次小生成树

    【YBTOJ】【Luogu P4180】[BJWC2010]严格次小生成树:

    链接:

    洛谷

    题目大意:

    求次小生成树。

    正文:

    本题有一个至关重要的性质:次小生成树只与最小生成树有一边之差。

    那么只用在最小生成树中加边,在环中的边里找一个最大的边减去。将所有这样的操作取最大,就是非严格最小生成树。有个“非”,是因为最大的边权可能与加边的边权相等,所以遇到这种情况要取次大值。

    倍增操作求值就能解决问题了。

    代码:

    const int N = 1e5 + 10, M = 3e5 + 10;
    
    inline ll Read()
    {
    	ll x = 0, f = 1;
    	char c = getchar();
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') f = -f, c = getchar();
    	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
    	return x * f;
    }
    
    // main
    int n, m; 
    int logN;
    ll ans = 1e17, sum;
    
    // edge
    struct Edge
    {
    	struct edge
    	{
    		int from, to, nxt;ll val; bool t;
    		bool operator < (edge &a) const
    		{
    			return val < a.val;
    		}
    	}e[M << 1];
    	int head[N], tot;
    	
    	void add(int u, int v, ll w)
    	{
    		e[++tot] = (edge) {u, v, head[u], w, 1}, head[u] = tot;
    	}
    } g, t;
    
    // Kruskal
    int fa[N];
    int Find(int k) {return k == fa[k]? k: fa[k] = Find(fa[k]);}
    void Kruskal()
    {
    	sort (g.e + 1, g.e + 1 + m);
    	for (int i = 1; i <= n; i++) fa[i] = i;
    	for (int i = 1; i <= m; i++)
    	{
    		int u = Find(g.e[i].from), v = Find(g.e[i].to);
    		if (u == v) continue;
    		fa[u] = v;
    		sum += g.e[i].val;
    		t.add(g.e[i].from, g.e[i].to, g.e[i].val);
    		t.add(g.e[i].to, g.e[i].from, g.e[i].val);
    		g.e[i].t = 0;
    	}
    }
    
    // LCA
    int dep[N];
    bool vis[N];
    int f[N][30];
    ll Max[N][30], sMax[N][30];
    
    queue <int> q;
    void BFS(int root)
    {
    	while(!q.empty()) q.pop();
    	q.push(root);
    	dep[root] = 1;
    	while(!q.empty())
    	{
    		int u = q.front(); q.pop();
    		vis[u] = 1;
    		for (int i = t.head[u]; i; i = t.e[i].nxt)
    		{
    			int v = t.e[i].to;
    			if (vis[v]) continue;
    			dep[v] = dep[u] + 1;
    			Max[v][0] = t.e[i].val;
    			sMax[v][0] = -1e17;
    			f[v][0] = u;
    			for (int j = 1; j <= logN; j++)
    			{
    				f[v][j] = f[f[v][j - 1]][j - 1];
    				sMax[v][j] = max(sMax[v][j - 1], sMax[f[v][j - 1]][j - 1]);
    				Max[v][j] = max(Max[v][j - 1], Max[f[v][j - 1]][j - 1]);
    				if (Max[v][j - 1] > Max[f[v][j - 1]][j - 1])
    					sMax[v][j] = max(sMax[v][j], Max[f[v][j - 1]][j - 1]);
    				if (Max[v][j - 1] < Max[f[v][j - 1]][j - 1])
    					sMax[v][j] = max(sMax[v][j], Max[v][j - 1]);
    			}
    			q.push(v);
    		}
    	}
    }
    
    int LCA(int u, int v)
    {
    	if (dep[u] > dep[v]) u ^= v ^= u ^= v;
    	for (int j = logN; ~j; j--)
    		if(dep[f[v][j]] >= dep[u]) 
    			v = f[v][j]; 
    	if (u == v) return u;
    	for (int j = logN; ~j; j--)
    		if(f[v][j] != f[u][j])
    			v = f[v][j], u = f[u][j];
    	u = f[u][0], v = f[v][0];
    	return u;
    }
    
    ll solve (int u, int v, ll k)
    {
    	ll ans = -1e17;
    	for (int j = logN; ~j; j--)
    		if(dep[f[u][j]] >= dep[v])
    		{
    			if (k != Max[u][j]) ans = max(ans, Max[u][j]);
    			else ans = max(ans, sMax[u][j]);
    			u = f[u][j];
    		}
    	return ans;
    }
    
    // main()
    int main()
    {
    	n = Read(), m = Read();
    	logN = log2(m) + 1;
    	for (int i = 1; i <= m; i++) 
    	{
    		int u = Read(), v = Read(); ll w = Read();
    		g.add(u, v, w);
    	}
    	
    	Kruskal();
    	BFS(1);
    	
    	for (int i = 1; i <= m; i++)
    	{
    		if (!g.e[i].t) continue;
    		int u = g.e[i].from, v = g.e[i].to;
    		ll tmp = sum, w = g.e[i].val;
    		int c = LCA(u, v);
    		tmp = tmp + w - max(solve (u, c, w), solve (v, c, w));
    		ans = min(ans, tmp);
    	}
    	printf ("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    【DB宝50】Oracle异构平台迁移之完全可传输导出导入(Full Transportable Export & Import)
    【DB宝49】Oracle如何设置DB、监听和EM开机启动
    【DB宝48】JumpServer:多云环境下更好用的堡垒机
    【DB宝47】企业知识分享+团队协作神器之Confluence
    【DB宝46】NoSQL数据库之CouchBase简介、集群搭建、XDCR同步及备份恢复
    【DB宝45】MySQL高可用之MGR+Consul架构部署
    【DB宝44】Oracle rac集群中的IP类型简介
    【DB宝43】MySQL误操作闪回恢复利器之my2sql
    【DB宝42】MySQL高可用架构MHA+ProxySQL实现读写分离和负载均衡
    【DB宝41】监控利器PMM的使用--监控MySQL、PG、MongoDB、ProxySQL等
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14984773.html
Copyright © 2011-2022 走看看