• HDU-1827


    听说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缩点后找每个分量中最便宜的加起来,入度为0的点必买.
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define inf 0x7fffffff
    #define maxn 1000+10
    #define maxm 2000+10
    struct Edge
    {
      int next,v;
    }edge[maxm];
    int n,m,index,top,tot,scc;
    int head[maxn],Stack[maxn],dfn[maxn],low[maxn],belong[maxn],cost[maxn];
    int indegree[maxn], outdegree[maxn];
    bool instack[maxn];
    int Max(int a,int b)
    {
      return a > b? a: b;
    }
    void init()
    {
        memset(head, -1, sizeof(head));
        memset(instack, false, sizeof(instack));
        memset(dfn, -1, sizeof(dfn));
        memset(low, 0, sizeof(low));
        memset(indegree, 0, sizeof(indegree));
        memset(outdegree, 0, sizeof(outdegree));
        memset(belong, 0,sizeof(belong));
        tot = 0;
        index = 0;
        top = 0;
        scc = 0;
    }
    void addedge(int u,int v)
    {
        edge[tot].next = head[u];
        edge[tot].v = v;
        head[u] = tot ++;
    }
    void tarjan(int u)
    {
        int v;
        dfn[u] = low[u] = ++index;
        Stack[top ++] = u;
        instack[u] = true;
        for(int i = head[u];i != -1;i = edge[i].next)
        {
            v = edge[i].v;
            if(dfn[v] == -1)
            {
              tarjan(v);
              if(low[v] < low[u])
               low[u] = low[v];
            }
            else
            {
              if(instack[v] && dfn[v] < low[u])
              {
                low[u] = dfn[v];
              }
            }
    
        }
        if(dfn[u] == low[u])
        {
            scc ++;
            int j;
            do
            {
                j = Stack[--top];
                instack[j] = false;  
                belong[j] = scc;
            }
            while(j != u);
        }
    }
    void solve()
    {
        for(int i = 1;i <= n;i ++)
        {
          if(dfn[i] == -1)
          tarjan(i);
        }
    }
    int main()
    {
        while(scanf("%d%d", &n, &m) != EOF)
        {
          init();
          for(int i = 1;i <= n;i ++)
            scanf("%d", &cost[i]);
          while(m --)
          {
              int a, b;
              scanf("%d%d", &a, &b);
              addedge(a, b);
          }
          solve();
          for(int i = 1;i <= n;i ++)
          {
            for(int j = head[i];j != -1;j = edge[j].next)
            {
                int u = i;
                int v = edge[j].v;
                if(belong[u] != belong[v])
                {
                  indegree[belong[v]] ++;
                }
            }
          }
          int ans = 0,cnt = 0;
          int mincost;
          for(int i = 1;i <= scc;i ++)
          {
            mincost = inf;
            if(indegree[i] == 0)
            {
                cnt ++;
                for(int j = 1;j <= n;j ++)
                {
                  if(belong[j] == i)
                  {
                    mincost = min(mincost, cost[j]);
                  }
                }
                ans += mincost;
            }
          }
    
         printf("%d %d
    ",cnt,ans);
        }
        return 0;
    }
  • 相关阅读:
    Yuan先生的博客网址
    Django的认证系统 auth模块
    Django 中间件使用
    Django Form表单验证
    Django ORM介绍 和字段及字段参数
    ajax 使用
    Java报表之JFreeChart
    POI
    MyBatis
    问题解决方法
  • 原文地址:https://www.cnblogs.com/iloveysm/p/13373382.html
Copyright © 2020-2023  润新知