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

UvaLive-4287-Proving Equivalences

2014-06-23 20:18 302 查看
有向图的双联通分量,有个结论是缩点后求出入度和出度的最大值就是答案

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
using namespace std;
const int maxn=40000;
const int maxm=80000;
int n,m,e,head[maxn],nxt[maxm],pnt[maxm];
int dfs_clock,scc_cnt,dfn[maxn],lowlink[maxn],sccno[maxn];
int in0[maxn],out0[maxn];
stack<int> s;
void AddEdge(int u,int v)
{
pnt[e]=v;nxt[e]=head[u];head[u]=e++;
}
void dfs(int u)
{
dfn[u]=lowlink[u]=++dfs_clock;
s.push(u);
for(int i=head[u];i!=-1;i=nxt[i])
{
if(!dfn[pnt[i]])
{
dfs(pnt[i]);
lowlink[u]=min(lowlink[u],lowlink[pnt[i]]);
}
else if(!sccno[pnt[i]])
lowlink[u]=min(lowlink[u],dfn[pnt[i]]);
}
if(lowlink[u]==dfn[u])
{
scc_cnt++;
for(;;)
{
int x=s.top();s.pop();
sccno[x]=scc_cnt;
if(x==u)
break;
}
}
}
void find_scc(int n)
{
dfs_clock=scc_cnt=0;
memset(sccno,0,sizeof(sccno));
memset(dfn,0,sizeof(dfn));
for(int i=1;i<=n;i++)
if(!dfn[i])
dfs(i);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
e=0;
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
AddEdge(u,v);
}
find_scc(n);
for(int i=1;i<=scc_cnt;i++)
in0[i]=out0[i]=1;
for(int u=1;u<=n;u++)
for(int i=head[u];i!=-1;i=nxt[i])
if(sccno[u]!=sccno[pnt[i]])
in0[sccno[pnt[i]]]=out0[sccno[u]]=0;
int a=0,b=0;
for(int i=1;i<=scc_cnt;i++)
{
if(in0[i])
a++;
if(out0[i])
b++;
}
int ans=max(a,b);
if(scc_cnt==1)
ans=0;
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: