zoukankan      html  css  js  c++  java
  • Codeforces Round #212 (Div. 2) D. Fools and Foolproof Roads

    我猜是哈夫曼算法。。。即贪心把当前连通分量集合中权值最小的两个连接起来,再合成一个加入集合,迭代下去。

    来不及交了,先贴下代码。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<queue>
    #include<string>
    #include<cmath>
    #include<fstream>
    #include<iomanip>
    
    using namespace std;
    
    #define LL long long
    #define MAXN 111111
    int n, m, u[MAXN], v[MAXN], w[MAXN];
    int p, q, f[MAXN<<1];
    LL fw[MAXN<<1];
    
    int finds(int x){
        if(f[x] == -1) return x;
        else return (f[x] = finds(f[x]));
    }
    #define cint const int
    #define inf 1e15
    
    bool cmp(cint a, cint b){
        return fw[a] < fw[b];
    }
    
    int t[MAXN], ans1[MAXN], ans2[MAXN];
    queue<int> ori, noi;
    
    bool have(int &n1, int &n2){
        bool f = false;
        int q1=-1, q11=-1, q2=-1, q22=-1;
        if(!ori.empty()){
            q1 = ori.front();  ori.pop();
            if(!ori.empty()) q11 = ori.front();
        }
        if(!noi.empty()){
            q1 = noi.front();   noi.pop();
            if(!noi.empty()) q22 = noi.front();
        }
        if(q1<0 || q2<0) return false;
        LL a1 = fw[q1] + fw[q2], a2 = (q11 > -1 ? fw[q1]+fw[q11] : inf),
           a3 = (q22 > -1 ? fw[q2] + fw[q22] : inf);
        LL mn = min(min(a1, a2), a3);
        if(a1 == mn){
            n1 = q1;
            n2 = q2;
    
        }
        else if(a2 == mn){
            ori.pop();  n1=q1;  n2=q11;
        }
        else{
            noi.pop();  n1=q2;  n2=q22;
        }
        return true;
    }
    
    int mp[MAXN<<1];
    void getans(int cnt){
        int i, j=0;
        for(i=1; i<=n; i++) if(f[i]==-1)
            t[j++] = i;
        sort(t, t+j, cmp);
        int mx = n + 1;
        while(!ori.empty()) ori.pop();      while(!noi.empty()) noi.pop();
        for(i=0; i<cnt; i++) ori.push(t[i]);
        for(i=0; cnt>q && p;){
            int n1, n2;
            if(have(n1, n2)){
                f[n1] = n2;
                LL t1 = (fw[n2] + fw[n1]) * 2 + 1, t2 = 1e9;
                fw[n2] = min(t1, t2);
                fw[mx] = fw[n2];
                mp[mx] = n2;
                noi.push(mx);
                if(n1 > n) n1 = mp[n1];
                if(n2 > n) n2 = mp[n2];
                ans1[i] = n1, ans2[i] = n2;
                cnt--;    i++;
                p--;        mx++;
            }
            else break;
        }
        if(p){
            int a1=-1, a2=-1;
            for(j=1; j<=n; j++) if(f[j]>-1){
                if(a1==-1) a1=j;
                else{ a2=j; break;}
            }
            while(p--)  ans1[i]=a1, ans2[i++]=a2;
        }
        for(j=0; j<i; j++) printf("%d %d
    ", ans1[j], ans2[j]);
    }
    
    int main(){
        //freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        while(scanf(" %d %d %d %d", &n, &m, &p, &q)==4){
            int i, j, cnt = n;
            for(i=0; i<m; i++) scanf(" %d %d %d", &u[i], &v[i], &w[i]);
            fill_n(f, n<<1, -1);
            fill_n(fw, n+1, 0);
            for(i=0; i<m; i++){
                int x = finds(u[i]), y = finds(v[i]);
                if(x != y){
                    f[x] = y;
                    fw[y]+=w[i];
                    cnt--;
                }
            }
            if(cnt < q || cnt - p > q || (cnt==n && q==n && p)){
                printf("NO
    ");     continue;
            }
            printf("YES
    ");
            getans(cnt);
        }
        return 0;
    }
    
  • 相关阅读:
    HDU Railroad (记忆化)
    HDU 1227 Fast Food
    HDU 3008 Warcraft
    asp vbscript 检测客户端浏览器和操作系统(也可以易于升级到ASP.NET)
    Csharp 讀取大文本文件數據到DataTable中,大批量插入到數據庫中
    csharp 在万年历中计算显示农历日子出错
    csharp create ICS file extension
    CSS DIV Shadow
    DataTable search keyword
    User select fontface/color/size/backgroundColor设置 字体,颜色,大小,背景色兼容主流浏览器
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3424592.html
Copyright © 2011-2022 走看看