I. Graph and Cycles(图论)

https://www.jisuanke.com/contest/7196/466924

题意:

给出一个n个点带权无向完全图,对于一个环(只考虑边可以有重点),其权值为任意两条相邻边的权值max的和。

现在将图分成多个环(无边交集,并集为完全图),图的值为每个环的权值之和,求其最小值。

解析:

思路:每条边,如果其权值大,那么尽可能接连权值较大的边。

将边按照权值排序,从大的开始取。

对于当前边的左右顶点,分别去判断是否可以连到之前的大权值边上,可以就连上去(link[i][0]表示第条边的左顶点连接的边)

由于每个点只会有一条空出来边(没连上的大权值边),所以用一个数组来记录没有匹配的大权边。

代码:

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-12-12.11.44
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e6+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

int n;
struct node{
    int x,y,w;
    bool operator<(const node &A)const{return w<A.w;}
}e[maxn];
int link[maxn][2];
int nowedge[1009];

LL ans;
bool vis[maxn];
void dfs(int ed,int preed){
    if(preed!=-1)
        vis[ed]=1,ans+=max(e[preed].w,e[ed].w);
    int p=0;
    if(e[ed].x==e[preed].x||e[ed].x==e[preed].y)p=1;
    int nexed=link[ed][p];
    if(vis[nexed])return;
    dfs(nexed,ed);
}

int main(){
    n=rd;
    int m=n*(n-1)/2;
    rep(i,1,m){
        e[i].x=rd;
        e[i].y=rd;
        e[i].w=rd;
    }
    sort(e+1,e+1+m);

    per(i,m,1){
        int x=e[i].x,y=e[i].y,w=e[i].w;
        int ed=nowedge[x];
        if(ed){
            int p=(e[ed].x==x?0:1);
            link[ed][p]=i;
            link[i][0]=ed;
            nowedge[x]=0;
        }
        else{
            nowedge[x]=i;
        }

        ed=nowedge[y];
        if(ed){
            int p=(e[ed].x==y?0:1);
            link[ed][p]=i;
            link[i][1]=ed;
            nowedge[y]=0;
        }
        else{
            nowedge[y]=i;
        }
    }

    rep(i,1,m){
        if(!vis[i])dfs(i,-1);
    }
    printf("%lld\n",ans);

    return 0;
}

/*_________________________________________________________end*/

发布了790 篇原创文章 · 获赞 348 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/105467930
今日推荐