zoukankan      html  css  js  c++  java
  • Summer Holiday

    Summer Holiday

    Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 27 Accepted Submission(s): 20
     
    Problem Description
    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
     
    Author
    威士忌
     
    Source
    HDOJ 2007 Summer Exercise(3)- Hold by Wiskey
     
    Recommend
    威士忌
     
    /*
    题意:略
    
    初步思路:找出强连通,然后贪心
    */
    #include<bits/stdc++.h>
    using namespace std;
    int cost[2007];
    int u[2007],v[2007];
    int allcost=0;
    int vis[2007];
    int money[2007];
    /**************************强连通模板******************************/
    const int maxn = 2000 + 7;
    vector<int> G[maxn];
    int n, m, k = 0, cnt = 0;
    int low[maxn];
    int dfn[maxn];
    int in[maxn];
    stack<int> s;
    
    void tarjan(int u) {
        low[u] = dfn[u] = ++k;
        s.push(u);
        for(int i = 0; i < G[u].size(); ++i) {
            int v = G[u][i];
            if(!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            } else if(!in[v]) {
                low[u] = min(low[u], dfn[v]);
            }
        }
        int v;
        if(dfn[u] == low[u]) {
            cnt++;
            do {
                v = s.top(); s.pop();
                in[v] = cnt;
            } while(u != v);
        }
    }
    /**************************强连通模板******************************/
    void init(){
        for(int i=1;i<=n;i++){
            G[i].clear();
        }
        k = 0, cnt = 0;
        memset(dfn,0,sizeof dfn);
        memset(low,0,sizeof low);
        memset(money,0x3f3f,sizeof money);
        memset(in,0,sizeof in);
        while(!s.empty()) s.pop();
        allcost=0;
    }
    int main(){
        // freopen("in.txt","r",stdin);
        while(scanf("%d%d",&n,&m)!=EOF){
            init();
            for(int i=1;i<=n;i++){
                scanf("%d",&cost[i]);
            }
            for(int i=0;i<m;i++){
                scanf("%d%d",&u[i],&v[i]);
                G[u[i]].push_back(v[i]);
            }
            for(int i=1;i<=n;i++){
                if(!dfn[i]) tarjan(i);
            }
            for(int i=1;i<=n;i++){
                money[in[i]]=min(cost[i],money[in[i]]);
            }
            
            for(int i=1;i<=cnt;i++){
                vis[i]=1;
            }
            
            for(int i=0;i<m;i++){
            if(in[u[i]]!=in[v[i]])
                vis[in[v[i]]] = 0;
            }
            
            int ans=0;
            for(int i=1;i<=cnt;i++){
                if(vis[i]){
                    ans++;
                    allcost+=money[i];
                }
            }
            // for(int i=1;i<=n;i++){
                // cout<<vis[i]<<" ";
            // }
            // cout<<endl;
            
            printf("%d %d
    ",ans,allcost);
        }
        return 0;
    }
  • 相关阅读:
    MSComm控件进行串口编程的基本步骤(转载)
    Linux C Socket编程原理及简单实例(转载)
    ubuntu14.04英文环境下安装中文输入法(转载)
    2015高工机器人年会第一批100名参会嘉宾名单公布
    中国式人机协作
    优傲机器人:协作机器人助力电子制造业智能转型
    netty学习笔记
    画图模板
    文本建模
    自定义IP协议
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6421974.html
Copyright © 2011-2022 走看看