[bzoj 2208] 연통 수 tarjan 축 점 & 상 압 상수 최적화
우선 tarjan 축 점 (분명), 그 다음 에 DAG 입 니 다.그 다음 에 축 소 된 강 한 연결 분량 에 가중치 가 함 유 된 점 의 개 수 를 주 고 강 한 연결 분량 에 대한 답 은 이 강 한 연결 분량 의 가중치 에 이 강 한 연결 분량 이 도달 할 수 있 는 점 의 개수 (자신 포함) 를 곱 하 는 것 이다.f [i] 로 강 한 연결 분량 i 가 도착 할 수 있 는 점 의 집합 을 나타 낸다 고 가정 하면 f [i] | = {f [j]} 이 존재 하 는 변 (u, v) 으로 u 가 강 한 연결 분량 i 에 있 고 v 가 j 에 있 으 면 이것 은 기억 화 로 쉽게 해결 할 수 있다 (전달 해도 된다).
바 이 너 리 로 표시 하면 폭발 (2 ^ n) 이 분명 하기 때문에 이 바 이 너 리 를 n / 30 개의 바 이 너 리 로 바 꾸 면 각 수의 크기 는 2 ^ 30 밖 에 안 됩 니 다.f 배열 의 시간 복잡 도 는 O (N + M) N / 30) = O (N ^ 3) 이지 만 n 이 최대 2000 이 고 1 / 30 이라는 아주 작은 상수 가 있 는 것 을 감안 하면 실제 운행 속 도 는 매우 빠르다.
AC 코드 는 다음 과 같 습 니 다.
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 2005
using namespace std;
int n,m,cnt,tp,tmp,dfsclk,s[N],pos[N],low[N],scc[N],sum[N],f[N][105];
int tot,fst[N],pnt[N*N],nxt[N*N]; bool vis[N],a[N][N];
void dfs(int x){
s[++tp]=x; pos[x]=low[x]=++dfsclk; int i;
for (i=1; i<=n; i++) if (a[x][i]){
if (!pos[i]){ dfs(i); low[x]=min(low[x],low[i]); } else
if (!scc[i]) low[x]=min(low[x],pos[i]);
}
if (low[x]==pos[x]){
for (sum[++cnt]=1; s[tp]!=x; tp--){
scc[s[tp]]=cnt; sum[cnt]++;
}
scc[x]=cnt; tp--;
}
}
void add(int aa,int bb){
pnt[++tot]=bb; nxt[tot]=fst[aa]; fst[aa]=tot;
}
void solve(int x){
if (vis[x]) return; vis[x]=1; int p,i;
for (p=fst[x]; p; p=nxt[p]){
int y=pnt[p]; solve(y);
for (i=0; i<=m; i++) f[x][i]|=f[y][i];
}
}
int work(int x){
int ans=0; for (; x; x-=x&(-x)) ans++; return ans;
}
int main(){
scanf("%d",&n); int i,j;
for (i=1; i<=n; i++){
char ch=getchar(); while (ch<'0' || ch>'1') ch=getchar();
for (j=1; j<=n; j++){
a[i][j]=(ch=='1'); ch=getchar();
}
}
for (i=1; i<=n; i++) if (!pos[i]) dfs(i);
int ans=0; m=n/30;
for (i=1; i<=n; i++) f[scc[i]][i/30]|=1<<(i%30);
for (i=1; i<=n; i++)
for (j=1; j<=n; j++) if (a[i][j] && scc[i]!=scc[j]) add(scc[i],scc[j]);
for (i=1; i<=cnt; i++) if (!vis[i]){
solve(i); for (j=0; j<=m; j++) ans+=sum[i]*work(f[i][j]);
}
printf("%d
",ans);
return 0;
}
by lych
2016.1.27
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
BZOJ 1023 SHOI 2008 cactus 선인장 그림 선인장 DP제목: 선인장 한 그루를 정해서 이 선인장의 직경을 구하다 우선Tarjan 축소점 쌍, 개vector 또는 체인 테이블은 각 점이 어떤 점 쌍에 속하는지, 그리고 각 점 쌍에 어떤 점이 있는지 기록한다. 어떤 두 켤...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.