• [題解/考試]國王飲水記


    前言:今日又考試了,一道斐波那契的入門題因為沒有特判0錯了一個點,兩道不會,結果連rk7、8都沒拿到,

    前天把鉛筆盒丟掉了,裡面有筆,耳機和U盤。U盤裡有做過的題,一些模板,寒假講的東西和課件,6個遊戲,一些安裝包和一些網址。

    發現丟掉以後就變得特別絕望,極度悲傷,可是這就是命運啊,你不接受那就去死好了。

    人活著本來就沒有什麼意義可言,尋找意義自然也是不可能尋找到的了。

    意義什麼的都是小孩子的事情,所以只能這樣活著了。

    與其如此那還不如把U盤裡的東西裝到腦子裡,也不必擔心什麼了。


    n個點,按順序有m條邊,每次詢問最大的最小生成森林的邊權和以及1號所在的聯通塊點數(包括自己)。

    輸入:第一行n,m。 接下來m行,每條邊的u,v,w。

    輸出:m行,每行 權值之和、1所在聯通塊的點數。

    數據規模:60% n,m<=1000

         100%n,m<=5000,1<=u,v<=n,u!=v,0<w<=10^5.

    對於圖G=(V,E),選取E' 屬於E,不產生重邊和環,并使|E'|最大,在這個前提下,使得總邊權最小,那麼G'=(V,E')就是最大的最小生成森林。


    要想拿到100分還不知道怎麼寫,不過對我來說60分的解法都不會......

    60%思路:

    每讀進來一條邊就可以用并查集亂搞,如果這兩點沒有聯通,那麼直接連上就行,sum加一下w就行

    如果已經聯通,那麼這條邊就有可能更新sum值,這裡可以每次都跑一次最小生成樹,重置sum再把選中的邊加上,但是複雜度有點高。

    dalao的代碼:(我的還沒改出來)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define R register int 
    using namespace std;
    struct edge {
        int u,v,w;
        bool operator < (const edge& y)const{return w<y.w;}
    }e[5001],tmp[5001];
    int n,m,f[5001],s[5001],cnt=1,ans,cntw,lst;
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=(ret<<1)+(ret<<3)+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    }
    inline void init(int k) {
        for(R i=1;i<=k;i++) f[i]=i,s[i]=1;
    }
    int getf(int x) {
        return x==f[x]?x:f[x]=getf(f[x]);
    }
    inline bool merge(int u,int v) {
        R uf=getf(u),vf=getf(v); if(uf==vf) return true;
        else {
            if(uf==1) {
                f[vf]=uf; s[uf]+=s[vf];
            }
            else if(vf==1) {
                f[uf]=vf; s[vf]+=s[uf];
            }
            else {
                f[vf]=uf; s[uf]+=s[vf];
            }return false;}
    }
    //    inline void kruskal(int k){
    //        for(R i=lst+1;i<=k;i++) tmp[i].u=e[i].u,tmp[i].v=e[i].v,tmp[i].w=e[i].w; ans=0;
    //        sort(tmp+1,tmp+k+1); init(k);
    //        for(R i=1;i<=k;i++){
    //            if(!merge(tmp[i].u,tmp[i].v)) ans+=tmp[i].w;
    //        }
    //    }
    namespace krusk{
        int fa[5001];
        inline void init(int k) {for(R i=1;i<=k;i++) fa[i]=i;}
        int getf(int x) {
            return x==fa[x]?x:fa[x]=getf(fa[x]);
        }
        inline bool merge(int u,int v) {
            R uf=getf(u),vf=getf(v); if(uf==vf) return true;
            else {fa[vf]=uf; return false;}
        }
        inline void kruskal(int k){
            for(R i=lst+1;i<=k;i++) tmp[i].u=e[i].u,tmp[i].v=e[i].v,tmp[i].w=e[i].w; ans=0;
            sort(tmp+1,tmp+k+1); init(n);
            for(R i=1;i<=k;i++){
                if(!merge(tmp[i].u,tmp[i].v)) ans+=tmp[i].w;
            }
        }
    }
    signed main() {
        n=g(),m=g(); for(R i=1;i<=n;i++) f[i]=i,s[i]=1;
        for(R i=1;i<=m;i++) e[i].u=g(),e[i].v=g(),e[i].w=g();
        for(R i=1;i<=m;i++) {
            R u=e[i].u,v=e[i].v,w=e[i].w;
            if(merge(u,v)) {
                krusk::kruskal(i);    
                cntw=min(cntw,ans);
            }
            else {
                cntw+=w;
            }
            printf("%d %d
    ",cntw,s[1]);
        }
        return 0;
    }

    以後可能會更新的吧

  • 相关阅读:
    Sqlserver 还原那些事
    Sqlserver CheckPoint 在三种恢复模式中的不同表现
    转 SQL Server中关于的checkpoint使用说明
    类继承中的 隐藏和重写的 区别
    转 关于C#中派生类调用基类构造函数的理解
    Sqlserver 笔记 持续更新
    Asp.net 执行回调操作后 无法更新ViewState的问题
    c# double decimal
    table用模板生成的问题
    MVC接收列表参数
  • 原文地址:https://www.cnblogs.com/superminivan/p/10486988.html
Copyright © 2020-2023  润新知