Weights on Vertices and Edges [Test, Atcoder]

W e i g h t s <mtext>   </mtext> o n <mtext>   </mtext> V e r t i c e s <mtext>   </mtext> a n d <mtext>   </mtext> E d g e s Weights\ on\ Vertices\ and\ Edges Weights on Vertices and Edges


D e s c r i p t i o n \mathcal{Description} Description

N N N 个点, M M M 条边的无向图, 有 边权, <stron>, 请在 每一个联通块 <mstyle mathcolor="blue"> </mstyle> \color{blue}{点权和} 大于 <mstyle mathcolor="blue"> </mstyle> \color{blue}{联通块中每条边权} 的前提下使得 边数 最大, 求 “最小割”. (雾</stron>

N , M &lt; = 1 0 5 N, M&lt;=10^5 N,M<=105


S o l u t i o n \mathcal{Solution} Solution

把每条边按 从小到大 排序, 依次加入图中, 相当于不断合并 联通块 .

每个联通块记录该联通块中 : n u m 不合法边数量: num :num ,

设当前加入的边权为 w w w, 合并时有 2 2 2 种情况 :

  1. &gt; = w : 总点权 &gt;= w: >=w:
    新的联通块 n u m num num 置为 0 0 0.
  2. &lt; w : 总点权 &lt; w: <w:
    新的联通块 n u m num num 置为 n u m 1 + n u m 2 + 1 num_1+num_2+1 num1+num2+1.

边所连的两个点 为同一联通块时, 同样按上述方法处理.

num_1,num_2为要合并的联通块的不合法边的数量


C o d e \mathcal{Code} Code

#include<bits/stdc++.h>
#define reg register

int read(){
        int s = 0, flag = 1;
        char c;
        while((c=getchar()) && !isdigit(c))
                if(c == '-'){ c = getchar(); flag = -1; break; }
        while(isdigit(c)) s = s*10 + c-'0', c = getchar();
        return s * flag;
}

typedef long long ll;
const int maxn = 100005;

int N;
int M;
int F[maxn];
int X[maxn];
int num[maxn];

struct Edge_2{ int a, b; ll w; } E[maxn];

int Find(int x){ return F[x]==x?x:F[x]=Find(F[x]); }

bool cmp(Edge_2 a, Edge_2 b){ return a.w < b.w; }

int main(){
        freopen("bridge.in", "r", stdin);
        freopen("bridge.out", "w", stdout);
        N = read(), M = read();
        for(reg int i = 1; i <= N; i ++) X[i] = read(), F[i] = i, num[i] = 0;
        for(reg int i = 1; i <= M; i ++){
                int u = read(), v = read(), w = read();
                E[i] = (Edge_2){ u, v, w };
        }
        std::sort(E+1, E+M+1, cmp);
        for(reg int i = 1; i <= M; i ++){
                int a = E[i].a, b = E[i].b, w = E[i].w;
                a = Find(a), b = Find(b);
                if(a != b){
                        if(X[a] + X[b] >= w) num[b] = 0;
                        else num[b] += num[a] + 1;
                        F[a] = b, X[b] += X[a];
                }else if(X[a] < w) num[a] ++;
        }
        int Ans = 0;
        for(reg int i = 1; i <= N; i ++){
                int t = Find(i);
                Ans += num[t];
                num[t] = 0;
        }
        printf("%d\n", Ans);
        return 0;
}


T e s t _ 5 , 16 Test\_5,16 Test_5,16

全部评论

相关推荐

09-29 00:03
门头沟学院 Java
点赞 评论 收藏
分享
来,说点可能被同行“骂”的大实话。🙊当初接数字马力Offer时,朋友都说:“蚂蚁的“内包”公司?你想清楚啊!”但入职快一年后的今天,我反而对他有了不一样的看法!🔹&nbsp;是偏见?还是信息差!之前没入职之前外面都在说什么岗位低人一等这类。实际上:这种情况不可至否,不能保证每个团队都是其乐融融。但我在的部门以及我了解的周边同事都还是十分好相处的~和蚂蚁师兄师姐之间也经常开一些小玩笑。总之:身份是蚂蚁公司给的,地位是自己挣的(一个傲娇女孩的自述)。🔹&nbsp;待遇?玩的就是真实!试用期工资全额发!六点下班跑得快(早9晚6或者早10晚7,动态打卡),公积金顶格交。别听那些画饼的,到手的钱和下班的时间才是真的(都是牛马何必难为牛马)。🔹&nbsp;能不能学到技术?来了就“后悔”!我们拥有权限直通蚂蚁知识库,技术栈多到学不完。说“学不到东西”的人,来了可能后悔——后悔来晚了(哈哈哈哈,可以不学但是不能没有)!💥&nbsp;内推地址:https://app.mokahr.com/su/ueoyhg❗我的内推码:NTA6Nvs走我的内推,可以直达业务部门,面试流程更快速,进度可查!今天新放HC,之前挂过也能再战!秋招已经正式开始啦~机会就摆在这,敢不敢来试一试呢?(和我一样,做个勇敢的女孩)
下午吃泡馍:数字马力的薪资一般哇,5年经验的java/测试就给人一万出头,而且刚入职第三天就让人出差,而且是出半年
帮你内推|数字马力 校招
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务