HDU 1827 Summer Holiday(Tarjan缩点)[通俗易懂]

HDU 1827 Summer Holiday(Tarjan缩点)

大家好,又见面了,我是全栈君。

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
题意:中文
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<limits.h>
typedef long long LL;
using namespace std;
const int INF=0x3f3f3f;

#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )

const int maxn=1100;
const int maxm=10000;
struct node{
    int u,v;
    int next;
}e[maxm];
int head[maxn],cntE;
int DFN[maxn],low[maxn];
int s[maxm],top,index,cnt;
int belong[maxn],instack[maxn];
int in[maxn],val[maxn];
int tt[maxn];//tt保存缩成的点中的最小值
int n,m;
void init()
{
    top=cntE=0;
    index=cnt=0;
    CLEAR(DFN,0);
    CLEAR(head,-1);
    CLEAR(instack,0);
}
void addedge(int u,int v)
{
    e[cntE].u=u;e[cntE].v=v;
    e[cntE].next=head[u];
    head[u]=cntE++;
}
void Tarjan(int u)
{
    DFN[u]=low[u]=++index;
    instack[u]=1;
    s[top++]=u;
    for(int i=head[u];i!=-1;i=e[i].next)
    {
        int v=e[i].v;
        if(!DFN[v])
        {
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],DFN[v]);
    }
    int v;
    if(DFN[u]==low[u])
    {
        cnt++;
        do{
            v=s[--top];
            belong[v]=cnt;
            instack[v]=0;
        }while(u!=v);
    }
}
void work()
{
    REPF(i,1,n)
      if(!DFN[i])  Tarjan(i);
    CLEAR(in,0);
    CLEAR(tt,INF);
    REPF(i,1,n)
    {
        if(tt[belong[i]]>val[i])
            tt[belong[i]]=val[i];
    }
    REPF(k,1,n)
    {
        for(int i=head[k];i!=-1;i=e[i].next)
        {
            int v=e[i].v;
            if(belong[k]!=belong[v])
               in[belong[v]]++;
        }
    }
    int ans=0;
    int num=0;
    REPF(i,1,cnt)
    {
        if(!in[i])
        {
            num++;
            ans+=tt[i];
        }
    }
    printf("%d %d\n",num,ans);
}
int main()
{
    int u,v;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=1;i<=n;i++)
            scanf("%d",&val[i]);
        for(int i=0;i<m;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        work();
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115806.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Oracle11g安装详细步骤(图文教程)

    Oracle11g安装详细步骤(图文教程)Oracle11g是J2EE初学者必学的数据库之一,下面就给大家介绍一下Oracle11g数据库的详细安装步骤。第一步:打开Oracle中文官网下载Oracle11g打开Oracle中文官网点击导航中的下载,找到数据库下载链接打开链接后,选择同意协议选项,并在下方找到Oracle11g的下载列表选择对应的版本进行下载,需要将File1和File2两个文件都下载下来第二步:解压文件,以

    2022年7月25日
    12
  • cocos2d-x 3.0游戏实例学习笔记 《跑酷》 完结篇–源代码放送

    cocos2d-x 3.0游戏实例学习笔记 《跑酷》 完结篇–源代码放送

    2021年12月2日
    42
  • python缩进错误提示(python缩进讲解)

    参考链接:Python语句,缩进和注释广告关闭腾讯云11.11云上盛惠,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!学习python与其他语言最大的区别就是,python的代码块不使用大括号{}来控制类,函数以及其他逻辑判断。python最具特色的就是用缩进来写模块。缩进…有时候,你觉得两行代码的缩进是一样的,但编译器仍然报错。这可能是因为一个地方使用空格来缩进,而另一个地方使用了tab键来缩进。碰到这种情况要统一…..

    2022年4月10日
    249
  • sql server下载安装步骤(sql2005安装教程图解)

    sql server下载安装步骤(sql2005安装教程图解)SQLServer2017下载安装教程第一步:打开浏览器,在浏览的搜索框中我们输入“SQLServer”。如图,会匹配出中文两条微软官方下载页面(一个页面内容是英文、一个页面内容是中文)。这里我们以中文的为例。第二步:点击进入下载页面后,可以看到如图所示页面,我们不要着急点击下载,因为这些SQLServer只能试用180天(大家从介绍中可以看到)。第三步:我们将网页下滑,可以看到…

    2022年4月18日
    416
  • 线程VS进程「建议收藏」

    线程VS进程「建议收藏」什么是线程、什么是进程在Java中要同时执行(如果是单核,准确的说是交替执行)多个任务,使用的是多线程,而要理解线程,我们先要了解什么是进程什么是线程。一般的定义:进程是指在操作系统中正在运行的一个应用程序,线程是指进程内独立执行某个任务的一个单元。怎么理解呢?比如说QQ是是一个进程,如果你在和A朋友语音聊天的同时和B朋友打字聊天,同时还在QQ群下载图片,这三个操作就相当于开启了三个线程,可以说有了线程之后我们设计的程序就可以一边执行A操作,一边执行B操作了。线程和进程有什么区别呢?首先最直观的

    2022年7月15日
    8
  • ubuntu下查看apk签名信息

    ubuntu下查看apk签名信息解压apk,使用命令:keytool-printcert-fileMETA-INF/CERT.RSA可以查看签名文件信息:所有者:C=Lily签发人:C=Lily序列号:523339c8有效期:TueOct2216:39:36CST2013至MonFeb2216:39:36CST3013证书指纹:   MD5:11:D8:65:

    2022年6月1日
    52

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号