3800 -- 【四校联考1】染色
Description
人人生而平等,然而后来人们逐渐选择了不同的道路,人与人之间,变得不再平等。你可能会因为染上恶人之色而堕落,成为社会的败类;你也可能因为染上善人之色,而在逆境中不断成长。但是,红与黑并非绝对的。所谓“近朱者赤,近墨者黑”,你能改变周遭的环境,那么周遭的环境也会影响你。在黑暗的人群中,善人之色是明亮的,而在明亮的人群中,善人之色的存在就会显得微薄。你的颜色,依靠着你自己的意志在选择。
如今,你获得了一次重生,你要为自己,以及你周围的人们,重新染上一种你真正想要的颜色。具体来说,你的圈子里总共有N个人,每个人你可以选择为其重新染色,或者不染。对于第i个人,如果他/她被重新染色,那么这将会对社会带来wi的改变。同时,朋友关系也会对社会带来改变,如果i,j是朋友,那么他/她们会对社会带来的改变w(i,j)满足
Input
Output
输出仅一行为一个整数,对社会产生的总的改变的最大值。
Hint
【数据规模与约定】
对于40%的数据,M=0。
对于另外40% 的数据,N,M≤20。
对于所有数据,N,M≤10^5。
第一次做的时候我就蠢了,最后20%妄图用分层图做,真是。。。
其实由于这道题的特殊性,我们可以将边权加在点权上,那么再让ans-边权,最后再累加所有大于0的点权'
对于这个贪心的正确性
我们可以分类讨论以下情况:
- 两个点都选,减去多加的一个边权正好
- 两个点都不选,那么我们根据题意减去边权也是正确的
- 如果选择了其中一个点,那么由于不应加边权,所以减去一个边权也是正确的。
实在是妙,但是这不是典型的,有一道典型的边权化点权我记不起来了。。。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
long long n,w[100005],u,v,m,W,ans=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>w[i];
cin>>m;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>W;
w[u]+=W,w[v]+=W;
ans-=W;
}
for(int i=1;i<=n;i++)
if(w[i]>0)ans+=w[i];
cout<<ans;
return 0;
}