您的位置:首页 > 产品设计 > UI/UE

uva 11324 The Largest Clique

2016-08-06 22:22 323 查看
Given a directed graph G, con- sider the following transformation.

First, create a new graph T(G) to have the same vertex set as G. Cre-

ate a directed edge between two vertices u and v in T(G) if and only

if there is a path between u and v in G that follows the directed

edges only in the forward direction. This graph T(G) is often called

the tran- sitive closure of G. We de ne a clique in a directed graph

as a set of vertices U such that for any two vertices u and v in U,

there is a directed edge either from u to v or from v to u (or both).

The size of a clique is the number of vertices in the clique. Input

The number of cases is given on the rst line of input. Each test case

describes a graph G. It begins with a line of two integers n and m ,

where 0  n  1000 is the number of vertices of G and 0  m  50 ; 000

is the number of directed edges of G. The vertices of G are numbered

from 1 to n . The following m lines contain two distinct integers u

and v between 1 and n which de ne a directed edge from u to v in G.

Output For each test case, output a single integer that is the size of

the largest clique in T(G).

很明显,对于每个scc里的点,要不然全选,要不然全不选。于是缩点成dag,以每个scc里包含的点数作为权值,问题变为在dag上找一条点权之和最大的路径。dp即可。

#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define M(a) memset(a,0,sizeof(a))
vector<int> to[1010],scc[1010];
stack<int> sta;
queue<int> que;
int dfn[1010],low[1010],tot,clo,num[1010],dp[1010],du[1010],m,n;
bool ins[1010],ren[1010];
void init()
{
int i;
M(dfn);
M(low);
tot=clo=0;
M(num);
M(dp);
M(du);
M(ins);
for (i=1;i<=1005;i++)
to[i].clear(),scc[i].clear();
while (!sta.empty())
sta.pop();
while (!que.empty())
que.pop();
}
void in()
{
int i,x,y;
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
to[x].push_back(y);
}
}
void dfs(int u)
{
int i,j,k,p,q,x,y,z,v;
dfn[u]=low[u]=++clo;
sta.push(u);
ins[u]=1;
for (i=0;i<to[u].size();i++)
{
v=to[u][i];
if (!dfn[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if (ins[v])
low[u]=min(low[u],dfn[v]);
}
if (low[u]==dfn[u])
{
tot++;
while (1)
{
p=sta.top();
sta.pop();
ins[p]=0;
num[p]=tot;
scc[tot].push_back(p);
if (p==u) break;
}
}
}
void make()
{
for (int i=1;i<=n;i++)
if (!dfn[i]) dfs(i);
}
void solve()
{
int i,j,k,p,q,u,v,x,y,z,ans=0;
for (i=1;i<=tot;i++)
{
M(ren);
for (j=0;j<scc[i].size();j++)
{
u=scc[i][j];
for (k=0;k<to[u].size();k++)
{
v=to[u][k];
if (num[v]!=i&&!ren[num[v]])
{
du[num[v]]++;
ren[num[v]]=1;
}
}
}
}
for (i=1;i<=tot;i++)
if (!du[i]) que.push(i);
while (!que.empty())
{
M(ren);
p=que.front();
que.pop();
dp[p]+=scc[p].size();
ans=max(ans,dp[p]);
for (i=0;i<scc[p].size();i++)
{
u=scc[p][i];
for (j=0;j<to[u].size();j++)
{
v=to[u][j];
if (p!=num[v]&&!ren[num[v]])
{
dp[num[v]]=max(dp[num[v]],dp[p]);
ren[num[v]]=1;
du[num[v]]--;
if (!du[num[v]]) que.push(num[v]);
}
}
}
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
init();
in();
make();
solve();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息