P1726 上白泽慧音

模板题了。。。


题意就是给你一个图,求最大的强联通分量和组成的这些点。

当然要用到tarjan算法啦,算法详情不讲。

求组成的点要注意:对一个时间状态的答案,要储存起来,才能判断字典序是否更小。

为了方便直接用std::vector,代码也很漂亮(自认为)。

只需要判断第一个元素即可,因为不可能一个点在多个强联通分量。

代码:

#include<cstdio>
#include<algorithm>
#include<vector>
const int maxn = 5005, maxm = 50005;
struct Edges
{
    int next, to;
} e[maxm << 1];
int head[maxn], tot;
int n, m;
int ans;
std::vector<int> anss, temp;
int dfn[maxn], low[maxn], dtot;
int stack[100005], top;
bool vis[maxn];
void tarjan(int u)
{
    dfn[u] = low[u] = ++dtot;
    stack[++top] = u; vis[u] = true;
    for(int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = std::min(low[u], low[v]);
        }
        else if(vis[v]) low[u] = std::min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        int cnt = 0;
        while(stack[top] != u)
        {
            int x = stack[top--]; vis[x] = false;
            temp.push_back(x); cnt++;
        }
        int x = stack[top--]; vis[x] = false;
        temp.push_back(x); cnt++;
        if(cnt > ans)
        {
            std::sort(temp.begin(), temp.end());
            anss = temp, ans = cnt; 
        } 
        else if(cnt == ans)
        {
            std::sort(temp.begin(), temp.end());
            if(temp[0] < anss[0]) anss = temp;
        }
        temp.clear();
    }
}
void link(int u, int v)
{
    e[++tot] = (Edges){head[u], v};
    head[u] = tot;
}
int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0')
    {
        if(ch == '-') s = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        ans = ans * 10 + ch - '0';
        ch = getchar();
    }
    return s * ans;
}
int main()
{
    n = read(), m = read();
    while(m--)
    {
        int u = read(), v = read(), opt = read();
        link(u, v);
        if(opt == 2) link(v, u);
    }
    for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i);
    printf("%d\n", ans);
    for(int i = 0; i < anss.size(); i++)
    {
        printf("%d ", anss[i]);
    }
    printf("\n");
    return 0;
}
posted @ 2018-07-08 14:50  Garen-Wang  阅读(109)  评论(0编辑  收藏  举报