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*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章