zoukankan      html  css  js  c++  java
  • HDU-1827 Summer Holiday

    To see a World in a Grain of Sand
    And a Heaven in a Wild Flower,
    Hold Infinity in the palm of your hand
    And Eternity in an hour.
                      —— William Blake

    听说lcy帮大家预定了新马泰7日游,Wiskey真是高兴的夜不能寐啊,他想着得快点把这消息告诉大家,虽然他手上有所有人的联系方式,但是一个一个联系过去实在太耗时间和电话费了。他知道其他人也有一些别人的联系方式,这样他可以通知其他人,再让其他人帮忙通知一下别人。你能帮Wiskey计算出至少要通知多少人,至少得花多少电话费就能让所有人都被通知到吗?

    Input多组测试数组,以EOF结束。
    第一行两个整数N和M(1<=N<=1000, 1<=M<=2000),表示人数和联系对数。
    接下一行有N个整数,表示Wiskey联系第i个人的电话费用。
    接着有M行,每行有两个整数X,Y,表示X能联系到Y,但是不表示Y也能联系X。
    Output输出最小联系人数和最小花费。
    每个CASE输出答案一行。
    Sample Input
    12 16
    2 2 2 2 2 2 2 2 2 2 2 2 
    1 3
    3 2
    2 1
    3 4
    2 4
    3 5
    5 4
    4 6
    6 4
    7 4
    7 12
    7 8
    8 7
    8 9
    10 9
    11 10
    Sample Output
    3 6

     

    求最小点基和最小权点基稞题。

    ①找出图G的所有强连通分量。

    ②从强连通分量中找出所有的最高强连通分量。也就是缩点后入度为0的点。

    ③从每个最高强连通分量中任取一点,组成点集B就是一个最小点基。

    从每个最高强连通分量中取权值最小的点,组成点集B就是一个最小点权基。

     

    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <queue>
    #include <stack>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define ll long long
    #define file(a) freopen(a".in","r",stdin); freopen(a".out","w",stdout);
    
    inline int gi()
    {
        bool b=0; int r=0; char c=getchar();
        while(c<'0' || c>'9') { if(c=='-') b=!b; c=getchar(); }
        while(c>='0' && c<='9') { r=r*10+c-'0'; c=getchar(); }
        if(b) return -r; return r;
    }
    
    const int inf = 1e9+7, N = 1007, M = 2007;
    int n,m,num,cnt,Deep,f[N],dfn[N],low[N],bl[N],V[N],C[N],rd[N];
    bool b[N];
    stack <int> s;
    struct data
    {
        int fr,nx,to;
    }da[M];
    
    inline void add (int fr,int to)
    {
        da[++num].fr=fr, da[num].to=to, da[num].nx=f[fr], f[fr]=num;
    }
    
    inline void tarjan (int o)
    {
        int i,to;
        dfn[o]=low[o]=++Deep;
        s.push(o); b[o]=1;
        for (i=f[o]; i; i=da[i].nx)
            {
                to=da[i].to;
                if (!dfn[to]) tarjan (to), low[o]=min(low[o],low[to]);
                else if (b[to]) low[o]=min(low[o],dfn[to]);
            }
        if (low[o] == dfn[o])
            {
                cnt++;
                do
                    {
                        to=s.top(); s.pop(); b[to]=0;
                        bl[to]=cnt; V[cnt]=min(V[cnt],C[to]);
                    }
                while(to != o);
            }
    }
    
    int main()
    {
    //    file("HDU-1827");
        int i,x,y;
        while (scanf ("%d%d",&n,&m) != EOF)
            {
                for (i=1; i<=n; i++) C[i]=gi(), V[i]=inf;
                for (i=1; i<=m; i++)
                    {
                        x=gi(), y=gi();
                        add (x,y);
                    }
                for (i=1; i<=n; i++) if(!dfn[i]) tarjan (i);
                for (i=1; i<=num; i++)
                    {
                        x=bl[da[i].fr], y=bl[da[i].to];
                        if (x != y) rd[y]++;
                    }
                x=0, y=0;
                for (i=1; i<=cnt; i++) if (!rd[i]) x++, y+=V[i];
                printf ("%d %d
    ",x,y);
                for (i=1; i<=n; i++) f[i]=C[i]=V[i]=dfn[i]=low[i]=bl[i]=0;
                for (i=1; i<=cnt; i++) rd[i]=0;
                for (i=1; i<=num; i++) da[i]={ 0,0,0 };
                num=Deep=cnt=0;
            }
        return 0;
    }

     

    欢迎在评论区提问质疑!

  • 相关阅读:
    ES6+ 现在就用系列(二):let 命令
    ES6+ 现在就用系列(一):为什么使用ES6+
    程序员之网络安全系列(六):动态密码
    程序员之网络安全系列(五):数字证书以及12306的证书问题
    程序员之网络安全系列(四):数据加密之非对称秘钥
    程序员之网络安全系列(三):数据加密之对称加密算法
    ddd
    vue加载时文件的执行顺序
    Kafka安装教程(详细过程)
    Kafka的安装与使用(转)
  • 原文地址:https://www.cnblogs.com/y142857/p/6883316.html
Copyright © 2011-2022 走看看