题解
A (Standard IO)
Description
Input
Output
Sample Input
输入1: 2 0 1 输入2: 5 4 2 1 2 2 5 4 3 3 1 输入3: 4 3 2 1 2 2 3 1 2 输入4: 5 11 7 1 3 4 2 1 5 4 2 2 5 1 3 4 1 2 3 4 1 5 1 1 5
Sample Output
输出1: 1 样例1解释:初始时有两个连接处,题目中要求至少每个连接处要连1个围墙,我们加一个围墙连接这两个连接处即可。 输出2: 1 样例2解释:连接编号为5的和编号为4的连接处即可。 输出3: 2 样例3解释:编号为4的连接处没有连接任何围墙,编号为3的连接处还需要一条。连接编号为4的和编号为3的连接处之后,编号为4的连接处与另外三个连接处中任意一个连一个围墙即可,注意连接处是不能自己和自己连接的。 输出4: 7
Data Constraint
1 for(int i=1;i<=m;i++)2 {3 scanf("%lld%lld",&x,&y);4 f[x]--;5 f[y]--;6 if(f[x]>=0) sum--;7 if(f[y]>=0) sum--8;8 }
sum为需要的每个点总边数,每两个所需要的边数组合起来才是题目中所要求的一条边(这里有一点难以理解,多想一下),
定义p为至少增加的边数,那么p=sum÷2向上取整,为什么要向上取整呢?因为如果sum是奇数,那么除下来还有一个所需边数没有配对,我们又要满足条件,所以不计算这个点是不行的,故向上取整。简单来说就是如果sum是个奇数,那么就多加上1个所需边数,让所有的所需边数都有可以配对的。代码实现如下:
1 long long p=sum;2 if(p%2==1) p++;3 p/=2;
处理完这些,我们还有遍历f数组找到其中的最大值为maxn。如果maxn大于p,那么我们的符合题意(至少增加就是最少增加)的答案就是maxn。因为至少还要有maxn条边连接到数值为maxn的这个点,p又小于了maxn,那么maxn这个点就肯定没有满足条件,故应该输出的是maxn。至于为什么会出现这样的情况,可以手推一下这组数据:
3 3 3
1 3
1 3
1 3
综合上面的推导,就可以做出来了,附上代码:
#include#include #include using namespace std;long long n,m,k,maxn,sum,a,b;long long f[100005];int main(){ scanf("%lld%lld%lld",&n,&m,&k); for(int i=1;i<=n;i++) f[i]=k; sum=n*k; for(int i=1;i<=m;i++) { scanf("%lld%lld",&a,&b); f[a]--; f[b]--; if(f[a]>=0) sum--; if(f[b]>=0) sum--; } for(int i=1;i<=n;i++) if(f[i]>maxn) maxn=f[i]; long long p=sum; if(p%2==1) p++; p/=2; printf("%lld",max(maxn,p)); return 0;}
出题的大佬说:
少考虑一种情况(maxn)50;
暴力70;
向下取整90;
没开long long90;
by:ルオ・テンイの锦依卫
未经作者允许,禁止转载!