[BZOJ] 1051: [HAOI 2006] 인 기 있 는 소.
Description
모든 소의 소원 은 가장 환 영 받 는 소 가 되 는 것 이다.지금 은 N 마리 의 소 가 있 습 니 다. M 대 정수 (A, B) 를 드 리 겠 습 니 다. 소 A 는 소 B 가 인기 가 있다 고 생각 합 니 다.이런 관 계 는 전달 적 인 것 으로 A 가 B 가 인기 가 있다 고 생각 하고 B 가 C 가 인기 가 있다 고 생각한다 면 우 A 도 우 C 가 인기 가 있다 고 생각한다.당신 의 임 무 는 소 몇 마리 가 모든 소 에 게 인기 가 있다 고 생각 하 는 지 구 하 는 것 입 니 다.
Input
첫 줄 두 개 N, M.다음 M 줄, 줄 당 두 개의 숫자 A, B 는 A 가 B 가 인기 가 있다 고 생각 한 다 는 뜻 이다.
Output
한 마리 의 소 가 모든 소 에 게 인기 가 있다 고 여 겨 지 는 지 세 어 보 자.
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
HINT
100% 데이터 N < = 10000, M < = 50000
사고: 처음에 사용 하고 집합 을 찾 을 수 있다 고 생각 했 지만 점 에 여러 개의 부모 노드 가 있 기 때문에 소박 하고 집합 을 찾 으 면 안 된다.
이렇게 하려 면 그림 을 만들어 야 한다. Tarjan 을 사용 하여 강 한 연결 분량 을 줄 이 고 그 다음 에 축 소 를 통 해 집합 하 는 요소 (사상 일 뿐 답 이 요구 하 는 것 은 일부분 이기 때문에 도 만 보면 된다) 를 살 펴 보고 하나의 노드 만 있 는 지 확인 해 야 한다.(모든 축 점 은 링 이다. 한 점 이 다른 축 점 을 가리 키 는 방향 이 있 으 면 이 축 점 에서 모든 요 소 는 축 점 중심 점 을 가리 키 는 팬 이다) 이렇게 하면 한 점 의 출 도 만 0 이라는 것 을 설명 한다. 즉, 한 개의 노드 만 있 으 면 된다. 그러면 이 노드 가 대표 하 는 축 점 중 점 수 는 answer 이다.
ps: Tarjan 이후 각 변 을 옮 겨 다 닌 다 고 생각 하기 시 작 했 습 니 다.; 그러나 이런 사상 은 잘못된 것 이다. 분석 할 때 단독 적 인 두 개의 축 점 간 의 관 계 를 보 았 기 때문이다. set 배 중 을 사용 하 더 라 도 두 개의 축 점 사이 에 배 중 을 실현 할 수 있 기 때문이다. 그러면 세 개의 축 점 으로 확장 하면 중복 계산 이 나타 날 수 있다.
/********************************************************
Time:88 ms
Memory:2888 kb
****************************************************************/
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
const int MAXN = 50050;
int head[MAXN],tot;
struct edge{
int to,w,Next;
}e[MAXN];
void ins(int a,int b,int w = 0)
{
e[++tot].Next = head[a];
e[tot].to = b;
e[tot].w = w;
head[a] = tot;
}
const int N = 10020;
int pre[N],dfs_clock,low[N];
int belong[N],scc,num[N];
stack<int> S;
bool stk[N];
void Tarjan(int u)
{
pre[u] = low[u] = ++dfs_clock;
S.push(u);
stk[u] = true;
int v;// u ;
for(int i = head[u];i;i = e[i].Next){
v = e[i].to;
if(pre[v] == 0){
Tarjan(v);
low[u] = min(low[u],low[v]);
}else if(stk[v]){
low[u] = min(low[u],pre[v]);
}
}
if(pre[u] == low[u]){//
++scc;
do{
v = S.top();
S.pop();stk[v] = false;
belong[v] = scc;
num[scc]++;
}while(v != u);
}
}
int id[MAXN];
int main()
{
int T,kase = 1;
MS0(head);tot = 0;
int n,m,a,b;
scanf("%d%d",&n,&m);
rep0(i,0,m){
scanf("%d%d",&a,&b);
ins(a,b);
}
scc = dfs_clock = 0;
rep1(i,0,n) pre[i] = low[i] = num[i] = belong[i] = 0;
rep1(i,1,n)if(pre[i] == 0)
Tarjan(i);
int ans = 0;MS0(id);
rep1(u,1,n){
for(int index = head[u];index;index = e[index].Next){
int v = e[index].to;
int bv = belong[v],bu = belong[u];
if(bv != bu && id[bu] == 0){//***
id[bu]++;// 0
}
}
}
rep1(i,1,scc)
if(id[i] == 0){
if(ans) return puts("0"),0;
ans = num[i];
}
printf("%d
",ans);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.