codeforces gym Graph and Cycles

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_45755679/article/details/113345960