2021银川Problem D. Farm(不保证正确性)

2021银川Problem D. Farm
(注:由于没有数据,暂不保证正确性)

题意:

有n个点,m个有权边,有q个限制条件,每个限制条件有两个选择:选u个边,选第v个边,两个选择至少要选一个。
问联通所有边的最小花费是多少?
0<=q<=16
1<=n<=1e5
1<=m<=5e5

题解:

不难看出q很小,因此我们可以用二进制的方法直接枚举直接枚举每个选择的情况。比如第i位是0表示第i个选择选的是边u,否则选的边v
这样复杂度是O(216ElogE)O(2^{16}ElogE)O(216ElogE),会超时
此时我们需要将E降低
我们想下,是否存在一些边是必选的,也就是不会受q的影响
限制的边指的是被q选中的边
我们将所有边进行排序,第一顺序为限制的边在前,非限制的边在后,第二顺序是费用从小到大
然后跑一边krusal,然后选到了n-1个边(最小生成树的边)
我们设n-1个边中限制边的数量为x(0<=x<=32),那么非限制边就是y=n-1-x(n-1<=y<=n-33)。也就是说无论限制边如何选择,有y个非限制边是一定会选择的,那我们就将这个y个边加入到最小生成树中,记录这y个边权值。这样就从原先n个点变成x+1个点未加入到最小生成树中
虽然只剩下x+1个点,但是任意两个点之间可能有很多边,我们可以将其减少,使得每两个点之间只有一个边
我们将所有边按照之前的排序方式再排,然后再跑一边最小生成树,将限定边和可以加入最小生成树的边存下来,这样得到新的边集,数量为tot
此时的tot最大为64,完全可以跑过
详细看代码(注:不保证正确)

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug( a, b ) printf ( "%s = %d\n", a, b );
using namespace std;
typedef long long          ll;
typedef unsigned long long ull;
typedef pair<int, int>     PII;
clock_t                    startTime, endTime;
// Fe~Jozky
const ll                                       INF_ll  = 1e18;
const int                                      INF_int = 0x3f3f3f3f;
void                                           read (){};
template <typename _Tp, typename... _Tps> void read ( _Tp &x, _Tps &...Ar )
{x         = 0;char c    = getchar ();bool flag = 0;while ( c < '0' || c > '9' )flag |= ( c == '-' ), c = getchar ();while ( c >= '0' && c <= '9' )x = ( x << 3 ) + ( x << 1 ) + ( c ^ 48 ), c = getchar ();if ( flag )x = -x;read ( Ar... );
}
template <typename T> inline void write ( T x )
{if ( x < 0 ){x = ~( x - 1 );putchar ( '-' );}if ( x > 9 )write ( x / 10 );putchar ( x % 10 + '0' );
}
void rd_test ()
{#ifdef ONLINE_JUDGE
#elsestartTime = clock ();freopen ( "in.txt", "r", stdin );
#endif
}
void Time_test ()
{#ifdef ONLINE_JUDGE
#elseendTime = clock ();printf ( "\nRun Time:%lfs\n",(double)( endTime - startTime ) / CLOCKS_PER_SEC );
#endif
}
const int MAXM = 500005;struct Edge
{int a, b, c, id;
} edge[MAXM], tmp[MAXM];
;int  fa[MAXM];
void init ( int m, Edge *edge )
{for ( int i = 1; i <= m; i++ ){fa[edge[i].a] = edge[i].a;fa[edge[i].b] = edge[i].b;}
}
int find ( int x )
{return fa[x] == x ? x : fa[x] = find ( fa[x] );
}
bool merge ( int x, int y )
{x = find ( x ), y = find ( y );if ( x == y )return 0;fa[x] = y;return 1;
}int  u[50], v[50];
bool key[MAXM], usd[MAXM];
/*
排序,第一顺序为限制,非限制,第二顺序为费用从小到大
跑一边krusal得到n-1个边
此时n-1个边中的非限制边是一定要选的
其中非限制边的数量为x,n-1-32<=x<=n-1
我们将这n-1个边中的非限制便直接选上然后将还可以加入最小生成树的边或者是限定选选出来,这是我们需要考虑的对这些边排序,第一顺序是非限制>限制,第二顺序边权<边权*/
bool cmp ( Edge x, Edge y )
{return key[x.id] == key[y.id] ? x.c < y.c : key[x.id] > key[y.id];
}
bool cmp1 ( Edge x, Edge y )
{return x.c < y.c;
}
int contraction ( int &n, int m, int &res )
{sort ( edge + 1, edge + m + 1, cmp );init ( m, edge );int tot = 0;for ( int i = 1; i <= m; i++ )if ( merge ( edge[i].a, edge[i].b ) )tmp[++tot] = edge[i];init ( tot, tmp );for ( int i = 1; i <= tot; i++ )if ( !key[tmp[i].id] ){merge ( tmp[i].a, tmp[i].b );n--;res += tmp[i].c;}tot = 0;for ( int i = 1; i <= m; i++ ){edge[i].a = find ( edge[i].a );edge[i].b = find ( edge[i].b );if ( key[edge[i].id] || edge[i].a != edge[i].b )edge[++tot] = edge[i];}return tot;
}
int removal ( int m ) //去掉重边
{sort ( edge + 1, edge + m + 1, cmp );init ( m, edge );int tot = 0;for ( int i = 1; i <= m; i++ )if ( key[edge[i].id] || merge ( edge[i].a, edge[i].b ) )edge[++tot] = edge[i];return tot;
}
int main ()
{rd_test();int n, m;scanf ( "%d%d", &n, &m );for ( int i = 1; i <= m; i++ ){int a, b, c;scanf ( "%d%d%d", &a, &b, &c );edge[i] = Edge{ a, b, c, i };}int q;scanf ( "%d", &q );for ( int i = 0; i < q; i++ ){scanf ( "%d%d", &u[i], &v[i] );key[u[i]] = key[v[i]] = 1;}int base = 0, res = INF_int;int tmp = contraction ( n, m, base );printf("现在的边有%d条\n",tmp);m       = removal ( tmp );printf("现在的边有%d条\n",m);sort ( edge + 1, edge + m + 1, cmp1 );for ( int state = 0; state < ( 1 << q ); state++ ){for ( int i = 0; i < q; i++ )usd[u[i]] = usd[v[i]] = 0;for ( int i = 0; i < q; i++ ){if ( state >> i & 1 )usd[u[i]] = 1;elseusd[v[i]] = 1;}init ( m, edge );int now = base, cnt = n;for ( int i = 1; i <= m; i++ )if ( usd[edge[i].id] ){if ( merge ( edge[i].a, edge[i].b ) )cnt--;now += edge[i].c;usd[edge[i].id] = 2;}for ( int i = 1; i <= m; i++ )if ( !usd[edge[i].id] && merge ( edge[i].a, edge[i].b ) )now += edge[i].c, cnt--;if ( cnt == 1 )res = min ( res, now );}printf ( "%d\n", ( res < INF_int ? res : -1 ) );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/316157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从B站的代码泄露事件中,我们能学到些什么?

先声明一下&#xff0c;本文不聊ISSUE中的七七八八&#xff0c;也不聊代码是否写的好&#xff0c;更不聊是不是跟蔡徐坤有关之类的吃瓜内容。仅站在技术人的角度&#xff0c;从这次的代码泄露事件&#xff0c;聊聊在代码的安全管理上&#xff0c;通常都需要做哪些事来预防此类事…

Educational Codeforces Round 117 (Rated for Div. 2)

A. Distance B. Special Permutation C. Chat Ban D.X-Magic Pair E. Messages F&#xff1a;没看F&#xff0c;好难的样子 G. Max Sum Array #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath>…

[Abp vNext 源码分析] - 3. 依赖注入与拦截器

一、简要说明ABP vNext 框架在使用依赖注入服务的时候&#xff0c;是直接使用的微软提供的 Microsoft.Extensions.DependencyInjection 包。这里与原来的 ABP 框架就不一样了&#xff0c;原来的 ABP 框架还需要抽象出来一个 IIocManager 用来管理整个 IoC 容器&#xff0c;现在…

hdu 7111-Remove

[hdu 7111] Brunhilda’s Birthday&#xff09; 题意&#xff1a; 和P6756 [BalticOI2013] Brunhilda’s Birthday&#xff09;一样的 给你p个质数集&#xff0c;您可以进行任意多次操作&#xff0c;每一次操作时&#xff0c;您选择一个素数pip_{i}pi​,这会使得n->⌊npi⌋…

Codeforces Round #757 (Div. 2)

A. Divan and a Store B. Divan and a New Project C. Divan and bitwise operations D1. Divan and Kostomuksha (easy version) D2. Divan and Kostomuksha (hard version) E. Divan and a Cottage 排序贪心 #include <iostream> #include <algorithm> #include…

dotnet core 微服务教程

这个教程主要是对于第一次使用dotnet core开发的同学。运行环境是在centos 7 &#xff0c;使用了docker容器。即这是一篇运行在linux的docker容器上的微服务的简单应用。一. 安装.NET SDK安装.NET之前&#xff0c;先安装一些依赖&#xff0c;运行下面的命令sudo rpm -Uvh https…

cf1552F. Telepanting

cf1552F. Telepanting 题意&#xff1a; 在一个坐标轴上&#xff0c;有n个传送门&#xff0c;格式为&#xff1a;xi,yi,si,可以从xi传送到yi&#xff0c;si表示状态&#xff0c;如果si为0&#xff0c;到位置xi时不会传送&#xff0c;si变为1.如果到达xi时si为1&#xff0c;则…

Educational Codeforces Round 118 (Rated for Div. 2)

A - Long Comparison B - Absent Remainder C - Poisoned Dagger D - MEX Sequences E - Crazy Robot 拿字符串比较 #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <cmath> #include <stack>…

eShopOnContainers 是一个基于微服务的.NET Core示例框架

找到一个好的示例框架很难&#xff0c;但不是不可能。大多数是小型Todo风格的应用程序&#xff0c;通常基于SimpleCRUD。值得庆幸的是&#xff0c;Microsoft已经为eShopOnContainers创建了一个基于微服务的.NET Core示例应用程序。eShopOnContainers是 .NET Core示例应用框架&a…

P1447 [NOI2010] 能量采集

P1447 [NOI2010] 能量采集 题意&#xff1a; 如果一棵植物与能量汇集机器(坐标为0&#xff0c;0)连接而成的线段上有 k 棵植物&#xff0c;则能量的损失为 2k 1 给你一个n*m的植物园&#xff0c;问能量损失是多少 1<n,m<1e5 题解&#xff1a; 本题所求式子为&#x…

P1232 [NOI2013] 树的计数

…调半天别的东西写错了&#xff0c;心力交瘁。 思路还是不会。。 具体就是二分&#xff0c;没想到&#xff0c;然后再贪心。 一直没整明白一个数它要往别的树走的条件是什么&#xff0c;日后研究。 #include <iostream> #include <cstdio> #include <cstring&…

「拥抱开源, 又见 .NET」系列第三次线下活动简报

「拥抱开源, 又见 .NET」随着 .NET Core的发布和开源&#xff0c;.NET又重新回到人们的视野。自2016年 .NET Core 1.0 发布以来&#xff0c;其强大的生命力让越来越多技术爱好者对她的未来满怀憧憬&#xff0c;越来越多的平台、框架热衷于为.NET Core不断更新的版本提供最有力的…

P3302 SDOI2013森林

P3302 [SDOI2013]森林 题意&#xff1a; 一片森林&#xff0c;有n个节点&#xff0c;m个边&#xff0c;现在有t个操作&#xff0c; Q x y k&#xff1a;Q x y k 查询点 x 到点 y 路径上所有的权值中&#xff0c;第 k 小的权值是多少 L x y 在点 x 和点 y 之间连接一条边。保证…

Codeforces Round #759 (Div. 2, based on Technocup 2022 Elimination Round 3)

感觉E思路明确只用了stl树状数组&#xff0c;F线段树复合修改&#xff0c;为什么都是2400。 A. Life of a Flower B. Array Eversion C. Minimize Distance E. Frequency Queries F. Non-equal Neighbours F : 首先 dp[i][j]sum[dp[i−1]]−dp[i−1][j]dp[i][j] sum[dp[i-1]] …

请给你的短信验证码接口加上SSL双向验证

序言去年年底闲来几天&#xff0c;有位同事专门在网上找一些注册型的app和网站&#xff0c;研究其短信接口是否安全&#xff0c;半天下来找到30来家&#xff0c;一些短信接口由于分析难度原因&#xff0c;没有继续深入&#xff0c;但差不多挖掘到20来个&#xff0c;可以肆意被调…

P2498 [SDOI2012]拯救小云公主

P2498 [SDOI2012]拯救小云公主 题意&#xff1a; 一个row * line的矩形&#xff0c;英雄在左下角(1,1),公主在右上角(row,line),有n个位置是boss。英雄现在要去公主那里&#xff0c;但是要避开boos&#xff0c;英雄决定找一条路径使到距离boss的最短距离最远。雄走的方向是任…

AtCoder Beginner Contest 230

A - AtCoder Quiz 3 B - Triple Metre C - X drawing 暂无 D - Destroyer Takahashi 暂无 贪心好难啊 E - Fraction Floor Sum F - Predilection G - GCD Permutation H - Bullion无 AAA int t;scanf("%d", &t);t t>42;printf("AGC%03d", t);BBB …

在Asp.Net Core中集成Kafka

在我们的业务中&#xff0c;我们通常需要在自己的业务子系统之间相互发送消息&#xff0c;一端去发送消息另一端去消费当前消息&#xff0c;这就涉及到使用消息队列MQ的一些内容&#xff0c;消息队列成熟的框架有多种&#xff0c;这里你可以读这篇文章来了解这些MQ的不同&#…

生成函数(母函数)

参考文章&#xff1a; 生成函数(母函数)——目前最全的讲解 《小学生都能看懂的生成函数从入门到升天教程》《生成函数全家桶》 Acwing 进阶课程–生成函数 引入 任意给定一个无限长的序列a0,a1....an....a_{0},a_{1}....a_{n}....a0​,a1​....an​.... 定义函数g(x)a0x0a1x…

AtCoder Beginner Contest 234

A - Weird Function B - Longest Segment C - Happy New Year! D - Prefix K-th Max E - Arithmetic Number F - Reordering G - Divide a Sequence 写个函数 int f(int x){return x*x2*x3;} int main() { int t;scanf("%d", &t);cout<<f(f(f(t)t)f(f(t…