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

    question:

    听说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

    题意:强联通分量内部是可以互相到达的,所以题目要求可转化为寻找强联通分量(tarjan算法),然后还要满足打电话花费最少
    tarjan算法模板:
    int dfn[maxn],low[maxn],stk[maxn],index=0,sccnum=0,top=0;
    void tarjan(int root){
        if(dfn[root])  return;
        dfn[root]=low[root]=++index;
        stk[++top]=root;
        for(int i=head[root];~i;i=e[i].ne){
            int v=e[i].to;
            if(!dfn[v]){
                tarjan(v);
                low[root]=min(low[root],low[v]);
            }
            else if(!scc[v]){
                low[root]=min(low[root],dfn[v]);
            }
        }
        if(low[root]==dfn[root]){
            sccnum++;
            for(;;){int x=stk[top--];
            scc[x]=sccnum;
            if(x==root)
            break;
            }
        }
    }
    
    

    solution:

    #include <cstdio>
    #include <vector>
    #include<algorithm> 
    using namespace std;
    #define inf 0x3f3f3f3f
    #define maxn 10010
    int n,m;
    vector<int> g[maxn];
    int sccnum;  
    int top; 
    int index; 
    int low[maxn],dfn[maxn],belong[maxn],stk[maxn];
    bool instack[maxn];
    int in[maxn],out[maxn],cost[maxn],ans[maxn];
    void Init()
    {
        sccnum=0,top=0,index=0;
        for(int i=1; i<=n; i++)
        {
            in[i]=out[i]=0;
            ans[i]=inf;
            g[i].clear();
            low[i]= dfn[i]= 0;
        }
    }
    void Tarjan(int root)
    {
        stk[top++]= root;
        instack[root]= 1;
        low[root]= dfn[root]= ++index;
        for(int i=0; i<g[root].size(); i++)
        {
            int v= g[root][i];
            if( !dfn[v] )   //如果v结点未访问过 
            {
                Tarjan(v);
                low[root]= min( low[v], low[root] );
            }
            else if( instack[v] )  //如果还在栈内 
                low[root]= min( low[root], dfn[v] );
        }
        if( low[root]==dfn[root] )   //后代不能找到更浅的点 
        {
            ++sccnum;
            int x;
            while(1){
                x= stk[--top];
                instack[x]= 0;
                belong[x]= sccnum;
                ans[sccnum]=min(ans[sccnum],cost[x]);
                if(root==x)
                break;
            }
        }
    }
     
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            Init();
            for(int i=1;i<=n;i++) 
            scanf("%d",&cost[i]);
            for(int i=1;i<=m;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                g[x].push_back(y);
            }
            for(int i=1;i<=n;i++)
            {
                if(!dfn[i])
                 Tarjan(i);
            }
            int ant=0,sum=0;
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<g[i].size();j++)
                {
                    int v=g[i][j];
                    if(belong[i]!=belong[v])
                    {
                        out[belong[i]]++,
                        in[belong[v]]++;
                    }
                }
            }
            for(int i=1;i<=sccnum;i++)
            {
                if(!in[i])
                {
                    ant++;
                    sum+=ans[i];
                }
            }
            printf("%d %d
    ",ant,sum);
        }
        return 0;
    }
    
    


  • 相关阅读:
    线段树的一种简化实现[原] by 踏雪赤兔
    C 语言qsort 函数详解
    【转载】Amit’s A star Page 中译文
    Poj3468 线段树 成段更新
    在VMware的CentOS中运行Cadence IC 615的怪现象
    安装非认证的chrome插件和设置文件夹的权限
    [模拟IC]基础知识1
    如何删除 Windows.old 文件夹?
    美国签证面签经历
    三个不同属性的GTD工具
  • 原文地址:https://www.cnblogs.com/hrlsm/p/13380090.html
Copyright © 2011-2022 走看看