记录编号 245563 评测结果 AAAAAAAAAA
题目名称 [WZOI 2011 S3] 消息传递 最终得分 100
用户昵称 GravatarRiolu 是否通过 通过
代码语言 C++ 运行时间 2.017 s
提交时间 2016-04-03 18:09:05 内存使用 6.12 MiB
显示代码纯文本
/*-------------------------------------------------
*  Author:Rainboy
*  time: 2016-03-30 15:42
*  © Copyright 2016 Rainboy. All Rights Reserved.
*-------------------------------------------------*/


/* -----------
 *  原理,:一个分量里的点都可以互相访问
 * 算法实现:
 *      1.初始化 dfn[i], low[i]
 *      2.对i所有相临的结点j
 *          1.if !vis[j] dfs[j]
 *          2.if vis[j] low[i] =dfn[j]
 *      3.if dfn[i] = low[i]
 * */


#include <cstdio>
#include <cstring>
#include<iostream>
#define maxn 200001 //最多的点
using namespace std;
bool instack[maxn] ={0}; // =false
int low[maxn];
int dfn[maxn] ={0};
int color[maxn]; // color[i] 点i的强连通分量
int stack[maxn],top; // 自己维护的stack ,可以用 STL stack
int cnt =0,indexk=0;
char ans[maxn];
//存图
int first[maxn];
int u[maxn],v[maxn],next[maxn];

void tarjan(int x){
    int j;
    dfn[x] = low[x] = ++indexk;
    instack[x] =true;
    stack[++top] = x;
    int e = first[x];
    for(; e != -1; e = next[e]){
        j = v[e];
        if( !dfn[j] ) // dnf[j] !=0 表示 这个点没有被访问过
        {
            tarjan(j);
            if(low[j] < low[x])
                low[x] = low[j];
        } 
        else if(instack[j] && dfn[j] < low[x])
            low[x] = dfn[j];
    }
	if(dfn[x] == low[x])
        {
            cnt++;int kk=0;
            do{
				kk++;
                j=stack[top--];
				ans[j]='T';
                instack[j] = false;
                color[j] = cnt;
            }
            while(j !=x);
			if(kk==1) ans[x]='F';
        }
}

int main(){
	freopen("messagew.in","r",stdin);
	freopen("messagew.out","w",stdout);
    top = 0;
    int i,j,k,n;
	int T;
    memset(first,-1,sizeof(first));
    scanf("%d%d",&T,&n);
    //读取图 这里用边集数组
    i=1;
	for(i=1;i<=n;i++){
		scanf("%d%d",&u[i],&v[i]);
        next[i] = first[u[i]];
        first[u[i]] = i;
    }
    for(i=1;i<=T;i++){ // 遍历所有点
        if(!dfn[i]) // 没有被访问过
            tarjan(i);
    }

	//cout<<cnt<<endl;

	/*for(k=1;k<=T;k++)
	{
		int t=color[k],ok=0;
			for(j=1;j<=T;j++)
				if(color[j]==t&&j!=k){
					cout<<"T"<<endl;ok=1;
					break;
					}
		if(ok==0) cout<<"F"<<endl;		
		}*/
	for(k=1;k<=T;k++)
		cout<<ans[k]<<endl;
    return 0;
}