CF1043E Train Hard, Win Easy
题意:
n个人有Ai和Bi两个属性,给出m个关系:xi yi表示xi和yi不能配对
i,j两人规定匹配的价值为min (Ai + Bj , Bi + Aj )
回答出每个人跟所有人配对(除开不能和自己匹配的人)的价值总和
题解:
两两匹配
取min (Ai + Bj , Bi + Aj )
假设 Ai + Bj < Bi + Aj
Ai - Aj < Bi -Bj
按照此规则排序即可,在前面的选x,后面的选y
再考虑m个不能匹配的情况
具体实现:先减去m个不能匹配的值,然后再加上所有匹配情况的值
对于第i个数,用它的y与前面的x匹配,用它的x与后面的y匹配
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
const int maxn=1000006;
struct node{int x,y,id;bool operator<(const node b){return x-y<b.x-b.y;}
}a[maxn];
int ans[maxn];
int sum[maxn],sum2[maxn];
signed main()
{cin>>n>>m;for(int i=1;i<=n;i++){scanf("%lld%lld",&a[i].x,&a[i].y);a[i].id=i;}for(int i=1;i<=m;i++){int u,v;scanf("%lld%lld",&u,&v);int h=min(a[u].x+a[v].y,a[u].y+a[v].x);ans[u]-=h;ans[v]-=h;}sort(a+1,a+n+1);int tot=0;for(int i = 1 ; i <= n ; i ++) sum[i] = sum[i - 1] + a[i].x;for(int i = n ; i >= 1 ; i --) sum2[i] = sum2[i + 1] + a[i].y;for(int i = 1 ; i <= n ; i ++) { ans[a[i].id] += sum[i - 1] + (i - 1) * a[i].y;ans[a[i].id] += sum2[i + 1] + (n - i) * a[i].x;}for(int i=1;i<=n;i++)cout<<ans[i]<<" ";return 0;
}