题目链接:https://codeforces.com/gym/102392/problem/J
题意:
给出一个带权的完全图,让你划分这些边,使得每个划分里的边可以构成一条回路。定义f(ex,ey)=max(ex,ey)。每个划分的权值等于f(e1,e2)+f(e2+e3)+f(e3,e4)…。现在求怎么划分使得每一组的权值之和最小。
题解:
因为是回路,所以对于每个点而言,必定有一条出去的边,和一条进入的边相对应,那么最优方案肯定是将第一大和第二大的相对应,第三大和第四大的相对应,以此类推。
代码:
#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int>pii;
const int MAXN=1e6+5;
const int mod=77797;
struct node
{
int u,v,w;
}f[MAXN];
std::vector<int> v[1005];
bool cmp(node a,node b)
{
return a.w>b.w;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n*(n-1)/2;i++)
{
cin>>f[i].u>>f[i].v>>f[i].w;
}
int m=n*(n-1)/2;
sort(f+1,f+1+m,cmp);
for(int i=1;i<=m;i++)
{
v[f[i].u].push_back(i);
v[f[i].v].push_back(i);
}
ll ans=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<v[i].size();j+=2)
{
ans+=f[v[i][j]].w;
}
}
cout<<ans<<endl;
}