atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges
Posted zhou2003
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges相关的知识,希望对你有一定的参考价值。
题目链接:Weights on Vertices and Edges
题目大意:有一个(n)个点(m)条边的无向图,点有点权,边有边权,问至少删去多少条边使得对于剩下的每一条边,它所在的联通块的点权值和大于等于该边的边权
其实是蛮简单的一道题目,为什么当时就自闭了呢。。。
正向删边明显不靠谱,于是我们考虑反向加边,答案就是(m-)加入的边数
我们按照边权排序,使用并查集维护点权值和,同时记录一个(cnt)数组表示当前存在于该联通块内但未加入答案的边数
如果说当前联通块的点权值和大于等于某条边权,那么按照枚举顺序我们知道所有边权小于等于该边的且在该联通块内的边均可以被加入的答案中
注意在合并的时候子节点的信息清零以免发生奇怪的事情
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int maxd=1000000007,N=100000;
const double pi=acos(-1.0);
typedef long long ll;
struct node{
int u,v,w;
}sq[100100];
bool operator < (const node &p,const node &q)
{
return p.w<q.w;
}
int n,m,fa[100100],cnt[100100],p[100100],ans=0;
ll sum[100100];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
int find(int x)
{
if (fa[x]==x) return fa[x];
fa[x]=find(fa[x]);
return fa[x];
}
int main()
{
n=read();m=read();int i;
for (i=1;i<=n;i++) {p[i]=read();sum[i]=p[i];}
memset(cnt,0,sizeof(cnt));
for (i=1;i<=n;i++) fa[i]=i;
for (i=1;i<=m;i++)
{
sq[i].u=read();sq[i].v=read();sq[i].w=read();
}
sort(sq+1,sq+1+m);
for (i=1;i<=m;i++)
{
int x=sq[i].u,y=sq[i].v,
fx=find(x),fy=find(y);
if (fx!=fy)
{
cnt[fx]+=(cnt[fy]+1);
sum[fx]+=sum[fy];
cnt[fy]=0;sum[fy]=0;
fa[fy]=fx;
}
else cnt[fx]++;
if (sum[fx]>=sq[i].w)
{
ans+=cnt[fx];
cnt[fx]=0;
}
}
printf("%d",m-ans);
return 0;
}
以上是关于atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019
atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges
nikkei2019_2_qual_f Mirror Frame