链接
[http://codeforces.com/contest/1043/problem/E]
题意
有n个人,每个人都有做出a,b题的分数,xi,yi,但是有些人是不能组队的,问你每个人和其他能组队的人最少分数和是多少
(组队时只能一个人做一个题,且不能相同)
分析
对于一个人和别人组队要么解决a,要么解决b, 他的分数是min(xi+yj,xj+yi);
所以我们只需要对统计xi+yj的情况和xj+yi的情况,若xi+yj<xj+yi 等价于xi-yi<xj-yj;
所以就对xi-yi;排序,后面就统计对其他人的分数最小和,最终减去不能组队的就是答案了具体看代码
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e5+10;
ll x[N],y[N];
ll ans[N];
int a[N];
vector<int> ve[N];
bool cmp(int b,int c){
return x[b]-y[b]<x[c]-y[c];
}
int main(){
int n,m,i,j;
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//freopen("in.txt","r",stdin);
cin>>n>>m;
int u,v;
for(i=1;i<=n;i++){
cin>>x[i]>>y[i];
a[i]=i;
}
for(j=1;j<=m;j++)
{
cin>>u>>v;
ve[u].push_back(v);
ve[v].push_back(u);
}
sort(a+1,a+n+1,cmp);
ll sum=0;
for(i=1;i<=n;i++){
ans[a[i]]=(i-1)*y[a[i]]+sum;
sum+=x[a[i]];
}
sum=0;
for(i=n;i>0;i--){
ans[a[i]]+=(n-i)*x[a[i]]+sum;
sum+=y[a[i]];
}
for(i=1;i<=n;i++)
for(j=0;j<ve[i].size();j++)
{
ll Min=min(x[i]+y[ve[i][j]],x[ve[i][j]]+y[i]);
ans[i]-=Min;
}
for(i=1;i<=n;i++)
cout<<ans[i]<<' ';
cout<<endl;
return 0;
}