CCF201509-4 高速公路

tarjan板子题
要注意的一点就是用do-while和while,count应该会相差1。

#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
#include <string.h>

using namespace std;
const int maxn =200001;
stack<int> s;
vector<int> grap[maxn];

int cnt, n,indexx,t, m, a, b, ans = 0;

int dfn[maxn], low[maxn], instack[maxn*2], vis[maxn];
void tarjan(int v)
{
  
    low[v] = dfn[v] = ++indexx;
    s.push(v);
    vis[v] = 1;
    instack[v] = 1;
    
    for(int i = 0 ; i < grap[v].size(); ++i)
    {
        int w = grap[v][i];
        if(!vis[w])
        {
            tarjan(w);
            low[v] = min(low[v], low[w]);
        }
        else if(instack[w])
        {
            low[v] = min(low[v], dfn[w]);
        }
    }
        int u;
        cnt = 0;
        if(low[v] == dfn[v])
        {
            
            do{
                u = s.top();
                cnt++;
                instack[u] = 0;
                s.pop();
            }while(u != v);
            
        }
    if(cnt > 1)
        ans += cnt * (cnt-1) / 2;
}
int main()
{
    
    cin>>n>>m;
    memset(vis, 0, sizeof(vis));
    for(int i = 1 ; i <= m ; ++i)
    {
        cin>>a>>b;
        grap[a].push_back(b);
    }
    for(int i = 1; i <= n ; ++i)
    {
        if(!vis[i])
            tarjan(i);
    }
    cout<<ans;
    return 0;
    
    
}


发布了10 篇原创文章 · 获赞 4 · 访问量 237

猜你喜欢

转载自blog.csdn.net/weixin_41414657/article/details/88550810