CodeForces770C【强连通分量+DFS序】

来源:互联网 发布:淘宝商城会员 编辑:程序博客网 时间:2024/06/07 04:52

思路:
显然按照他的意思建图肯定不行。
对于u所需要先解决的v[], 建边 u -> v[], 然后就是判断一下每个main 课程是否在一个环里,或者是不是他需要先修的课程在环里,这样子就不满足。
然后我就很爆炸,窝很蠢地想到了Tarjan,然后就处理了一下那些强连通分量,然后就是用来判断是不是在环里,不满足。
然后就是对每个main 课程 DFS搜,然后就好啦,然后智障的窝第一次发现这个拓扑排序的逆序竟然是DFS序。。。
因为菜啊!!不会一次DFS就能判断= =、就瞄了瞄题解。。我就不多bb了…思路基本一样。。。但是人家的写法。。(窝看到的时候内心是崩溃的)

void dfs(int u) {    if (color[u] == 0) {        color[u] = 1;        for (int to: g[u])            dfs(to);        color[u] = 2;        ord.push_back(u);    } else if (color[u] == 1)        cycle = true;}

然后我的搓代码。。(其实单组案例可以去掉那些没必要的初化)

#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#include<vector>#include<map>#include<set>#include<algorithm>#include<list>using namespace std;typedef pair<int,int> PII;typedef long long LL;#define mem(a, b) memset(a, b, sizeof(a))#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1const double eps = 1e-9;const double pi = acos(-1.0);const int INF = 0x3f3f3f3f;const int Maxn = 1e5 + 10;int n, k;struct Edge{    int v, nex;}edge[Maxn<<1];int head[Maxn], tol;int sp[Maxn];bool spi[Maxn];void init(){    tol = 0;    memset(head, -1, sizeof(head));}void add(int u, int v){    edge[tol] = (Edge){v, head[u]}, head[u] = tol++;}bool flag, wa[Maxn];int low[Maxn], dfn[Maxn];int sta[Maxn], cnt, top, ind;bool vis[Maxn];int id[Maxn];void Tarjan(int u){    if(flag) return;    low[u] = dfn[u] = ++ind;    vis[u] = true;    sta[++top] = u;    int v;    for(int i=head[u]; ~i;i=edge[i].nex){        v = edge[i].v;        if(!dfn[v]){            Tarjan(v);            low[u] = min(low[u], low[v]);        }        else if(vis[v]) low[u] = min(low[u], dfn[v]);    }    if(low[u] == dfn[u]){        int temp;        int sum = 0;        bool f = false;        cnt++;        while(1){            temp = sta[top];            if(spi[temp]) f = true;            vis[temp] = false;            id[temp] = cnt;            top--;            sum++;            if(temp == u) break;        }        if(sum > 1 && f){            flag = true;            return;        }        if(sum > 1) wa[cnt] = true;    }}bool Judge(){    memset(wa, false, sizeof(wa));    memset(dfn, 0, sizeof(dfn));    memset(low, 0, sizeof(low));    memset(vis, false, sizeof(vis));    top = cnt = top = 0;    for(int i=1;i<=n;i++){        if(flag) return false;        if(!dfn[i]) Tarjan(i);    }    if(flag) return false;    return true;}int ans[Maxn], ans_num;bool used[Maxn];void DFS(int u){    int v;    if(flag) return;    if(wa[id[u]]){        flag = true;        return;    }    used[u] = 1;    for(int i=head[u];~i;i=edge[i].nex){        v = edge[i].v;        if(vis[v] || used[v]) continue;        DFS(v);    }    if(!vis[u]){        ans[ans_num++] = u;        vis[u] = true;    }}void solve(){    flag = false;    if(!Judge()){        puts("-1");//        puts("aaa");        return;    }    int u;    memset(vis, false, sizeof(vis));    memset(used, false, sizeof(used));    for(int i=1;i<=k;i++){        if(flag){            puts("-1");            return;        }        u = sp[i];        if(vis[u] || used[u]) continue;        DFS(u);    }    if(flag){        puts("-1");        return;    }    printf("%d\n", ans_num);    for(int i=0;i<ans_num;i++)    {        if(i) printf(" ");        printf("%d", ans[i]);    }}int main(){    int m;    int u, v;    scanf("%d%d", &n, &k);    init();    memset(spi, false, sizeof(spi));    for(int i=1;i<=k;i++){        scanf("%d", &sp[i]);        spi[sp[i]] = true;    }    for(int i=1;i<=n;i++){        scanf("%d", &m);        u = i;        while(m--){            scanf("%d", &v);            add(u, v);        }    }    solve();    return 0;}/*4 141 21 31 41 23 31 2 32 2 31 304 141 31 11 21 3*/
原创粉丝点击