问题描述
WZland开办了一个俱乐部(这里面可以干任何的事情),这引来了许多的人来加入。俱乐部的人数越来越多,关系也越来越复杂……
俱乐部的人来自各个地方,为了增加友谊,俱乐部举行了一次晚会。晚会上又进行了一个传话游戏,如果A认识B,那么A收到某个消息,就会把这个消息传给B,以及所有A认识的人(如果A认识B,B不一定认识A),所有人从1到N编号。
现在给出所有“认识”关系,俱乐部的负责人WZland的国王想知道一个十分简单的问题:如果A发布一条新消息,那么会不会经过若干次传话后,这个消息传回给了A,1≤A≤N。但是WZland的国王是出了名的数学差,幸好的是你在他的身边,于是他就将这个问题交给你来解决。


输入格式
输入数据中的第一行是两个数N和M,两数之间有一个空格,表示人数和认识关系数。
接下来的M行,每行两个数A和B,表示A认识B(1A, BN,AB)。
输出格式
输出文件中一共有N行,每行一个字符“T”或“F”。第i行如果是“T”,表示i发出一条新消息会传回给i;如果是“F”,表示i发出一条新消息不会传回给i。
样例输入输出
message.in 
4 6
1 2
2 3
4 1
3 1
1 3
2 3
message.out
T
T
T
F


数据规模
对于30%的数据,N≤1000,M≤20000;
对于50%的数据,N≤10000,M≤100000;
对于100%的数据,N≤100000,M≤200000;
认识关系可能会重复给出。
时间限制
1s

消息传递(cogs 1001)_输入输出消息传递(cogs 1001)_#include_02
/*
  tarjan缩点后,看i所在的缩点中点的个数是否大于1。
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define M 100010
using namespace std;
int num[M],low[M],instack[M],vis[M],belong[M],sum[M],s

[M*2],cnt,indexx,top;
int head[M],n,m;
struct node
{
    int v,pre;
};node e[M*2];
int read()
{
    char c=getchar();int num=0,flag=1;
    while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
    while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
    return num*flag;
}
void add(int i,int x,int y)
{
    e[i].v=y;
    e[i].pre=head[x];
    head[x]=i;
}
void tarjan(int v)
{
    num[v]=low[v]=++indexx;
    vis[v]=instack[v]=1;
    s[++top]=v;
    for(int i=head[v];i;i=e[i].pre)
    {
        int w=e[i].v;
        if(!vis[w])
        {
            tarjan(w);
            low[v]=min(low[v],low[w]);
        }
        else if(instack[w])
          low[v]=min(low[v],num[w]);
    }
    int u;
    if(num[v]==low[v])
    {
        ++cnt;
        do
        {
            u=s[top--];
            instack[u]=0;
            belong[u]=cnt;
            sum[cnt]++;
        }while(u!=v);
    }
}
int main()
{
    freopen("messagew.in","r",stdin);
    freopen("messagew.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        add(i,x,y);
    }
    for(int i=1;i<=n;i++)
      if(!vis[i])tarjan(i);
    for(int i=1;i<=n;i++)
      if(sum[belong[i]]>1)printf("T\n");
      else printf("F\n");
    return 0;
}
View Code