UVA - 11324 The Largest Clique 강연통 축소점 + 기억화 dp
3213 단어 uva
먼저 원도에 대해 강연통축점을 실시하여 새로운 그림을 얻었다. 이 새 그림은 체인 모양으로 나무 구조와 유사하다.
새 그림을 기억화 dp하여 가장 긴 체인을 구하고 각 점의 값은 현재 강연통 분량점의 개수이다.
/*
Tarjan set
Col 。
*/
#include <iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
#define MAXN 2005
#define MAXM 100005
struct node
{
int to,next;
}edge[MAXM],edge2[MAXM];
bool have[1005][1005];
int sums[1005];
int head[MAXN],head2[MAXN],en,en2;
bool root[MAXN];
int low[MAXN],dfn[MAXN],stack[MAXN],top,set[MAXN],col,num;
bool vis[MAXN],instack[MAXN];
int dp[MAXN];
int n;
int m;
void addedge(int a,int b)
{
edge[en].to=b;
edge[en].next=head[a];
head[a]=en++;
}
void addedge2(int a,int b)
{
edge2[en2].to=b;
edge2[en2].next=head2[a];
head2[a]=en2++;
}
void tarjan(int u)
{
vis[u]=1;
dfn[u]=low[u]=++num;
instack[u]=true;
stack[++top]=u;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(!vis[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else
if(instack[v])
low[u]=min(dfn[v],low[u]);
}
if(dfn[u]==low[u])
{
int j;
col++;
do
{
j=stack[top--];
instack[j]=false;
set[j]=col;
}
while (j!=u);
}
}
void init()
{
int i;
en=en2=top=col=num=0;
memset(head,-1,sizeof(head));
memset(head2,-1,sizeof(head2));
memset(instack,0,sizeof(instack));
memset(vis,0,sizeof(vis));
memset(set,-1,sizeof(set));
memset(have,0,sizeof(have));
memset(sums,0,sizeof(sums));
memset(root,true,sizeof(root));
memset(dp,-1,sizeof(dp));
}
int ans;
int dfs(int now,int fa)
{
if(~dp[now]) return dp[now];
int maxs=sums[now];
for(int i=head2[now];~i;i=edge2[i].next)
{
int to=edge2[i].to;
if(to!=fa)
{
maxs=max(maxs,sums[now]+dfs(to,now));
}
}
return dp[now]=maxs;
}
int main()
{
int a,b;
int cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
}
for(int i=1;i<=n;i++)
if(!vis[i])tarjan(i);
for(int i=1;i<=n;i++)
{
sums[set[i]]++;
for(int j=head[i];~j;j=edge[j].next)
{
int to=edge[j].to;
if(set[i]!=set[to]&&!have[set[i]][set[to]])
{
addedge2(set[i],set[to]);
root[set[to]]=false;
have[set[i]][set[to]]=have[set[to]][set[i]]=true;
}
}
}
ans=0;
for(int i=1;i<=col;i++)
{
if(root[i])
{
dfs(i,-1);
ans=max(ans,dp[i]);
}
}
printf("%d
",ans);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
UVA - 10986 Sending email(Dijkstra 인접 테이블 + 우선 순위 대기열 최적화)제목 대의: s점에서 t점까지의 최소 거리를 구하는 그림을 주세요. 확인: 적나라한 최단길이지만 n이 너무 크면 인접 행렬을 사용할 수 없기 때문에 Dijkstra에 대한 인접표 + 우선 대기열 최적화가 필요합니다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.