问题描述:
思路:
Tarjan求强连通分量,求得后,对于每一个强联通分量如果有k个结点,若k>1则强联通对结点的数量为k*(k-1)/2,若k=1则为0。
不知道Tarjan的盆友看这里(大佬讲解Tarjan),我等小白讲不清楚,向大佬膜拜学习。
代码
def tarjan(u):
global idx
global Bcnt
idx+=1
dfn[u]=low[u]=idx #每次dfs,u的次序号增加1
s.append(u)#将u入栈
for i in range(len(dt[u])): #//访问从u出发的边
v=dt[u][i]
if dfn[v]==0: #//如果v没被处理过
tarjan(v);#//dfs(v)
low[u]=min(low[u],low[v])
#//u点能到达的最小次序号是它自己能到达点的最小次序号和连接点v能到达点的最小次序号中较小的
elif v in s:
low[u]=min(low[u],dfn[v])
#//如果v在栈内,u点能到达的最小次序号是它自己能到达点的最小次序号和v的次序号中较小的
if dfn[u]==low[u] :
v=s[-1]
s.pop()
Belong[v]=Bcnt;
while u != v:
v=s[-1]
s.pop()
Belong[v]=Bcnt
Bcnt+=1
def work():
global Bcnt
ssum=0
for i in range(n):
if dfn[i]==0:
tarjan(i)
for i in range(Bcnt):
tc=[]
for j in range(n):
if Belong[j]==i:
tc.append(j)
if len(tc)>1:
it=len(tc)
ssum+=((it-1)*it)//2
return ssum
if __name__=="__main__":
idx,Bcnt=0,0
s=[];
cc=[]
n,m=list(map(int,input().split()))
dfn=[0]*n
low=[0]*n
Belong=[0]*n;
dt=[[] for _ in range(n)]
for i in range(m):
x,y=list(map(int,input().split()))
x,y=x-1,y-1
dt[x].append(y)
ssum=work()
print(ssum)
不知道哪里出错了,就只有60分,T~T
请看到的大佬指教一下。