最近切的两题SCC的tarjan POJ1236 POJ2186

两题都是水题,1236第一问求缩点后入度为0的点数,第二问即至少添加多少条边使全图强连通,属于经典做法,具体可以看白书
POJ2186即求缩点后出度为0的那个唯一的点所包含的点数(即SCC里有多少点)
//poj1236
#include<iostream>
#include<cstdio>
#include<string.h>
#define maxn 6000
int now=0,next[maxn],head[maxn],point[maxn],num=0,dfn[maxn],low[maxn],instack[maxn];
int stack[maxn],belong[maxn],top,count,in[maxn],out[maxn];
int min(int a,int b)
{
    if (a<b)return a;else return b;
}
int max(int a,int b)
{
    if (a>b)return a;else return b;
}
void add(int x,int y)
{
    next[++now]=head[x];
    head[x]=now;
    point[now]=y;
}
void tarjan(int k)
{
    int u;
    instack[k]=true;
    dfn[k]=low[k]=++num;stack[++top]=k;
    for(int i=head[k];i!=0;i=next[i])
    {
        u=point[i];
        if (dfn[u]==0)
        {
            tarjan(u);
            low[k]=min(low[k],low[u]);
        }
        else if (instack[u])low[k]=min(dfn[u],low[k]);
    }
    if (low[k]==dfn[k])
    {
        ++count;
        do
        {
            u=stack[top--];
            instack[u]=false;
            belong[u]=count;
        }while(u!=k);
    }
}
int main()
{
    int n,t;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)while (1)
    {
        scanf("%d",&t);
        if (t==0)break;
        else add(i,t);
    }
    for(int i=1;i<=n;i++)if (dfn[i]==0)tarjan(i);
    for(int i=1;i<=n;i++)
    {
        for(int j=head[i];j!=0;j=next[j])
        {
            int u=point[j];
            if (belong[i]!=belong[u])
            {
                out[belong[i]]++;
                in[belong[u]]++;
            }
        }
    }
    int countout=0,countin=0;
    for(int i=1;i<=count;i++)
    {
        if (out[i]==0)countout++;
        if (in[i]==0)countin++;
    }
    if (count==1)printf("1\n0\n");
    else printf("%d\n%d\n",countin,max(countout,countin));
    return 0;
}
 

//poj2186

#include<iostream>

#include<cstdio>

#include<string.h>

#define maxn 50010

using namespace std;

intnow=0,next[maxn],head[maxn],point[maxn],num=0,dfn[maxn],low[maxn],instack[maxn];

int stack[maxn],belong[maxn],top,count,out[maxn],p[maxn];

void add(int x,int y)

{

next[++now]=head[x];

head[x]=now;

point[now]=y;

}

void tarjan(int k)

{

instack[k]=1;

stack[++top]=k;

low[k]=dfn[k]=++num;

int u;

for(inti=head[k];i!=0;i=next[i])

{

u=point[i];

if (dfn[u]==0)

{

tarjan(u);

low[k]=min(low[u],low[k]);

}

else if (instack[u]==1)low[k]=min(dfn[u],low[k]);

}

if (low[k]==dfn[k])

{

++count;

do

{

u=stack[top--];

instack[u]=0;

belong[u]=count;

p[count]++;

}while(u!=k);

}

}

int main()

{

int n,m,x,y,ans=0;

scanf("%d%d",&n,&m);

for(int i=1;i<=m;i++)

{

scanf("%d%d",&x,&y);

add(x,y);

}

for(int i=1;i<=n;i++)

if (dfn[i]==0)tarjan(i);

for(int i=1;i<=n;i++)

{

for(int j=head[i];j!=0;j=next[j])

{

int u=point[j];

if(belong[i]!=belong[u])out[belong[i]]++;

}

}

int flag=0;

for(inti=1;i<=count;i++)

{

if (ans!=0 &&out[i]==0){flag=1;break;}

if(out[i]==0)ans=p[i];

}

if(flag==0)printf("%d\n",ans);else printf("0\n");

return 0;

}

时间: 2024-10-11 07:04:19

最近切的两题SCC的tarjan POJ1236 POJ2186的相关文章

BestCoder Round #4 前两题 hdu 4931 4932

第一题太水了.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int a[6]; 7 int main(){ 8 int cas; 9 scanf( "%d", &cas ); 10 while( cas-- ){ 11 for( int i = 0; i <

(莫队算法)两题莫队算法统计数量的入门题

因为这两题差不多,而且比较简单,就放一起,做了这题,这种题目就是巨水的题了.随便写都行. CodeForces - 86D  Powerful array 题意: 多次查询数列中从L到R每个数字出现次数的平方乘这个数字的和. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #include <map> 6 #includ

codechef 两题

前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM,不过他求得是XOR最大值,原理类似.. B:KMP居然写搓了,后来一直改,题目放个链接好了:http://www.codechef.com/LTIME14/problems/TASHIFT. 我么可以对B字符串复制一下,然后再对A字符串求出NEXT数组,再匹配的过程中求出匹配最大长度时的位置, 刚开始我没想

挑战JavaScript正则表达式每日两题

不少学习JS开发的同学可能对正则表达式抱有不屑一顾的态度,认为用到时再查查不就行了.以前在学习其他语言,例如JAVA和C#时,我就有这么一种观点--反正看了不用就忘. 但是,JS开发中,你无论是自己开发还是观看别人的模块或者第三方库,你会更为频繁地使用到正则表达式.因此,正则表达式一下子变得不再是可有可无. 从本篇开始,我打算使用大致10多天时间,开发二十多个题,都是有关正则表达式的使用问题,权作JAVASCRIPT开发朋友的一种小型讨论聚会,但绝不是什么"擂台"赛.问题给出后,将在下

Educational Codeforces Round 58 (Rated for Div. 2) (前两题题解)

感慨 这次比较昏迷最近算法有点飘,都在玩pygame...做出第一题让人hack了,第二题还昏迷想错了 A Minimum Integer(数学) 水题,上来就能做出来但是让人hack成了tle,所以要思考一下具体的过程 原本我是认为直接把d进行累加看什么时候不在那个segment内也就是那个范围之内结果tle 今天思考一下发现有两种情况 ①如果d本来就是小于左边界的那么就输出d就可以了,因为样例明确提示有原来的数也可以 ②然后就是如果d在范围之内或者范围外可以用余数来确定具体的数公式是: an

每天两题04

本来昨晚就准备看两个题的,结果下班回来躺了一下就睡着了,今天继续,嘿嘿(^.^) 题目一:二进制中1的个数 题目描述:输入一个整数,输出该数二进制表示中 1 的个数. 思路:第一眼看到这个题目的我想法是首先将这个数转成二进制字符串,然后通过遍历这个字符串中的每一个元素是不是等于1,然后用个int类型的数值去计算,代码如下: public static int oneNum(int n) { String string = Integer.toBinaryString(n); int count

BestCoder Round #13(前两题)

这一次又只出了一题,第二题没有分析好,竟然直接copy代码,不过长见识了.. 第一题给了一些限制条件,自己没有分析好,就去乱搞,结果各种不对,后来有读题才发现..暴力乱搞.. 题目: Beautiful Palindrome Number Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 657    Accepted Submissio

BestCoder 2nd Anniversary的前两题

Oracle Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 79    Accepted Submission(s): 41 Problem Description There is once a king and queen, rulers of an unnamed city, who have three daughters

LeetCode算法编程(两题)

今天看到酷壳推荐的国外编程LeetCode算法编程网站,上面目前有154道算法题,感觉很有意思,平常工作也比较忙,现在很少有时间来锻炼算法相关的东西,有空的时候静下心来,温习下基础,活跃下自已的思路,也是有必要的.先做了几道,后面会陆续补充其它的题目. 1.题目-PlusOne Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored s