1008 挖沟 kruskal+prim板子

 链接:https://ac.nowcoder.com/acm/contest/26077/1008
来源:牛客网

题目描述


    胡队长带领HA实验的战士们玩真人CS,真人CS的地图由一些据点组成,现在胡队长已经占领了n个据点,为了方便,将他们编号为1-n,为了隐蔽,胡队长命令战士们在每个据点出挖一个坑,让战士们躲在坑里。由于需要在任意两个点之间传递信息,两个坑之间必须挖出至少一条通路,而挖沟是一件很麻烦的差事,所以胡队长希望挖出数量尽可能少的沟,使得任意两个据点之间有至少一条通路,顺便,尽可能的∑d[i][j]使最小(其中d[i][j]为据点i到j的距离)。

输入描述:

第一行有2个正整数n,m,m表示可供挖的沟数。
接下来m行,每行3个数a,b,v,每行描述一条可供挖的沟,该沟可以使a与b连通,长度为v。

输出描述:

输出一行,一个正整数,表示要使得任意两个据点之间有一条通路,至少需要挖长的沟。(数据保证有解)
示例1

输入

复制
2 2
1 2 1
1 2 3

输出

复制
1
示例2

输入

复制
3 3
1 2 3
2 3 4
1 3 5

输出

复制
7

备注:

对于100%的测试数据:
1 ≤ n ≤ 100000
1 ≤ m ≤ 500000
1 ≤ v ≤ 10000

分析

kruskal板子,关键是记得定义结构体。

对边排序。o(mlogm)

 

prim。优先队列优化o((n+m)logm)

暴力就是n^2

//-------------------------代码----------------------------

#define int ll
const int N = 5e5+10;
int n,m;
int p[N];
struct node {
    int a,b,w;
}g[N];

int find(int x) {
    return x == p[x] ? x:p[x] = find(p[x]);
}

bool cmp(node a,node b) {
    return a.w<b.w;
}

void solve()
{
    cin>>n>>m;
    fo(i,1,N-1) p[i] = i;
    fo(i,1,m) {
        int a,b,v;cin>>a>>b>>v;
        g[i] = {a,b,v};
    }
    sort(g+1,g+1+m,cmp);int ans = 0;
    fo(i,1,m) {
        int a = g[i].a,b = g[i].b,w = g[i].w;
        if(find(a) != find(b)) {
            p[find(b)] = find(a);ans += w;
        }
    }
    cout<<ans<<endl;
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

//-------------------------代码----------------------------

#define int ll
const int N = 5e5+10;
int n,m;
V<pii> g[N];
bool vis[N];
void prim() {
    priority_queue<pii,V<pii>,greater<pii>> q;
    q.push({0,1});
    int ans = 0;
    while(q.size()) {
        auto t = q.top();
        q.pop();
        int ver = t.second,w = t.first;
        if(vis[ver]) continue;
        vis[ver] = 1;
        ans += w;
        for(auto p:g[ver]) {
            if(vis[p.x]) continue;
            int ww = p.y;
            q.push({ww,p.x});
        }
    }
    cout<<ans<<endl;
}

void solve()
{
    cin>>n>>m;
    fo(i,1,m) {
        int a,b,v;
        cin>>a>>b>>v;
        g[a].pb({b,v});
        g[b].pb({a,v});
    } 
    prim();
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-16 15:59  er007  阅读(23)  评论(0编辑  收藏  举报