码迷,mamicode.com
首页 > 其他好文 > 详细

HDU-2767-ProvingEquivalences

时间:2019-05-06 18:49:27      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:long   强连通图   lse   queue   init   name   就是   cstring   oid   

链接:https://vjudge.net/problem/HDU-2767

题意:

给一个图,求最少需要几条边将其连成一个强连通图

思路:

tarjan,缩点,考虑缩点后的图,出度为0的点和入度为0的点,而所需要的边就是出度为0,和入度为0的点的较大值。

代码:

#include <iostream>
#include <memory.h>
#include <string>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
#include <cstdio>
#include <set>
#include <iterator>
#include <cstring>
using namespace std;

typedef long long LL;
const int MAXN = 2e4+10;

vector<int> G[MAXN];
stack<int> St;
int Dfn[MAXN], Low[MAXN];
int Vis[MAXN], Dis[MAXN][2]; // 0:in, 1:out
int Fa[MAXN];
int n, m;
int times, cnt;

void Init()
{
    for (int i = 1;i <= n;i++)
        G[i].clear(), Fa[i] = i;
    memset(Dfn, 0, sizeof(Dfn));
    memset(Low, 0, sizeof(Low));
    memset(Vis, 0, sizeof(Vis));
    memset(Dis, 0, sizeof(Dis));
    times = cnt = 0;
}

void Tarjan(int x)
{
    St.push(x);
    Vis[x] = 1;
    Dfn[x] = Low[x] = ++times;
    for (int i = 0;i < G[x].size();i++)
    {
        int node = G[x][i];
        if (Dfn[node] == 0)
        {
            Tarjan(node);
            Low[x] = min(Low[x], Low[node]);
        }
        else if (Vis[node] == 1)
            Low[x] = min(Low[x], Dfn[node]);
    }
    if (Low[x] == Dfn[x])
    {
        ++cnt;
        while (x != St.top())
        {
            Fa[St.top()] = cnt;
            Vis[St.top()] = 0;
            St.pop();
        }
        Fa[St.top()] = cnt;
        Vis[St.top()] = 0;
        St.pop();
    }
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        cin >> n >> m;
        Init();
        int l, r;
        for (int i = 1;i <= m;i++)
        {
            cin >> l >> r;
            G[l].push_back(r);
        }
        for (int i = 1;i <= n;++i)
            if (!Dfn[i])
                Tarjan(i);
        if (cnt == 1)
            cout << 0 << endl;
        else
        {
            for (int i = 1;i <= n;i++)
            {
                for (int j = 0;j < G[i].size();j++)
                {
                    int node = G[i][j];
                    if (Fa[i] != Fa[node])
                        ++Dis[Fa[i]][1], ++Dis[Fa[node]][0];
                }
            }
            int in = 0, out = 0;
            for (int i = 1;i <= cnt;i++)
            {
                if (Dis[i][0] == 0)
                    in++;
                if (Dis[i][1] == 0)
                    out++;
            }
            cout << max(out, in) << endl;
        }
    }

    return 0;
}

  

HDU-2767-ProvingEquivalences

标签:long   强连通图   lse   queue   init   name   就是   cstring   oid   

原文地址:https://www.cnblogs.com/YDDDD/p/10821269.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!