88分 #5第一行错求助

P2272 [ZJOI2007] 最大半连通子图

lukelin @ 2018-09-10 20:19:08

RT

贴个代码,顺便问下有没有dalao有过同样的经历QAQ

#include <cstdio>
#include <map>
#include <queue>

using namespace std;

struct Edge{
    int to;
    int next;
} edges[1000005], edges2[1000005];

int head[100005], edge_num = 0, head2[100005], edge_num2 = 0;

void add_edge(int from, int to){
    edges[++edge_num].to = to;
    edges[edge_num].next = head[from];
    head[from] = edge_num;
}

void add_edge2(int from, int to){
    edges2[++edge_num2].to = to;
    edges2[edge_num2].next = head2[from];
    head2[from] = edge_num2;
}

int low[100005], dfn[100005], ind = 0;
int stack[100005], s_tp = 0;
unsigned char in_stack[100005];
int cl[100005], cl_num = 0;
int cl_size[100005];
map<pair<int,int>, unsigned char> mp;

void Tarjan(int u){
    low[u] = dfn[u] = ++ind;
    in_stack[u] = 1;
    stack[++s_tp] = u;
    int c_e = head[u], v;
    while (c_e != 0){
        v = edges[c_e].to;
        if (!dfn[v]){
            Tarjan(v);
            if (low[v] < low[u])
                low[u] = low[v];
        }
        else if (in_stack[v]){
            if (dfn[v] < low[u])
                low[u] = dfn[v];
        }
        c_e = edges[c_e].next;
    }
    if (low[u] == dfn[u]){
        ++cl_num;
        while (stack[s_tp] != u){
            ++cl_size[cl_num];
            cl[stack[s_tp]] = cl_num;
            --s_tp;
        }
        ++cl_size[cl_num];
        --s_tp;
        cl[u] = cl_num;
    }
    in_stack[u] = 0;
}

int rd[100005];
int topo[100005], topo_num = 0;
queue<int> que;
long long C[100005];

void Topo(){
    int i;
    for (i = 1; i <= cl_num; i++)
        if (rd[i] == 0)
            que.push(i);
    int u, c_e;
    while (!que.empty()){
        u = que.front();
        que.pop();
        C[u] = 1;
        topo[++topo_num] = u;
        c_e = head2[u];
        while (c_e != 0){
            rd[edges2[c_e].to]--;
            if (rd[edges2[c_e].to] == 0){
                que.push(edges2[c_e].to);
            }
            c_e = edges2[c_e].next;
        }
    }
}

long long K[100005];

int main(){
    int n, m;
    long long x;
    scanf("%d %d %lld", &n, &m, &x);
    int a, b, i;
    for (i = 0; i < m; i++){
        scanf("%d %d", &a, &b);
        add_edge(a, b);
    }
    for (i = 1; i <= n; i++){
        if (!dfn[i]){
            Tarjan(i);
        }
    }
    int c_e, v;
    pair<int, int> _new;
    for (i = 1; i <= n; i++){
        c_e = head[i];
        while (c_e != 0){
            v = edges[c_e].to;
            if (cl[i] != cl[v]){
                _new.first = cl[i];
                _new.second = cl[v];
                if (!mp[_new]){
                    add_edge2(cl[i], cl[v]);
                    mp[_new] = 1;
                    rd[cl[v]]++;
                }
            }
            c_e = edges[c_e].next;
        }
    }
    Topo();
    long long maxK = 0, maxC = 0;
    for (i = topo_num; i >= 1; i--){
        K[i]+=cl_size[i];
        if (maxK < K[i]){
            maxK = K[i];
            maxC = (C[i] % x);
        }
        else if (maxK == K[i]){
            maxC += C[i];
            maxC %= x;
        }
        c_e = head2[i];
        while (c_e != 0){
            v = edges2[c_e].to;
            if (K[i] > K[v]){
                K[v] = K[i];
                C[v] = C[i];
                C[v] %= x;
            }
            else if (K[i] == K[v]){
                C[v] += C[i];
                C[v] %= x;
            }
            c_e = edges2[c_e].next;
        }
    }
    printf("%lld\n%lld", maxK, maxC);
    return 0;
}

代码丑陋,见谅


|