图论|2021-08-10 SSL 模拟赛 T2

2021-08-10 SSL 模拟赛 T2 【图论|2021-08-10 SSL 模拟赛 T2】依旧是没有标题的一题
图论|2021-08-10 SSL 模拟赛 T2
文章图片

图论|2021-08-10 SSL 模拟赛 T2
文章图片

题面就不复制了,太长了。
思路: 显然,我们争取用最少的费用获取所有情报,那么每一条线路都必须是有用的,就是删掉这条线后将会出现一部分情报无法获得的情况。
那这不就是个最小生成树的模板题吗?
我们把派出一个人所需要的费用看做是向不存在图中的 0 号节点连一条边,那么这题就转化成了一道最小生成树的模板题。
我们用克鲁斯卡尔算法去解决。
最小生成树的实现就不写了,也比较简单,时间复杂度O ( m ? l o gm ) O(m*log~m) O(m?log m)
代码:

#include #include #include #include #include #include #define r register #define rep(i,x,y) for(r ll i=x; i<=y; ++i) #define per(i,x,y) for(r ll i=x; i>=y; --i) using namespace std; typedef long long ll; ll n,g[1010][1010],v[1010],top,f[1010]; ll MST,tot; struct node { ll x,y,k; }a[1010*1010]; bool cmp(node x,node y) { return x.k'9') if(ch=='-') f=-1; res=res*10+ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return res*f; } int main() { scanf("%lld",&n); rep(i,1,n) rep(j,1,n) {g[i][j]=in(); a[++top].x=i; a[top].y=j; a[top].k=g[i][j]; } rep(i,1,n) {scanf("%lld",&v[i]); a[++top].x=0; a[top].y=i; a[top].k=v[i]; a[++top].x=i; a[top].y=0; a[top].k=v[i]; } rep(i,0,n) f[i]=i; sort(a+1,a+top+1,cmp); //最下生成树的排序 rep(i,1,top) {ll x=a[i].x,y=a[i].y,val=a[i].k; if(find(x)!=find(y)) {make(x,y); ++tot; MST+=val; if(tot>=n) break ; } } printf("%lld",MST); return 0; }

    推荐阅读