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

总算把USACO的受欢迎奶牛做出来了

时间:2015-01-20 23:28:47      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

有一些奶牛,其中某些奶牛受其他奶牛欢迎。每头奶牛都喜欢自己,同时都追随它喜欢奶牛的爱好。如果A喜欢B,而B喜欢C,那么A也会喜欢C。如果所有人都喜欢某头奶牛,那么这头奶牛就称之为绝对奶牛。

现在有N头奶牛,同时告诉你M条A喜欢B的信息,请你计算出有多少头绝对奶牛。

输入描述:

输入文件第一行是N和M。此后M行,每行两个整数A,B(1<=A,B<=N),表示奶牛B受奶牛A欢迎,也就是奶牛A喜欢奶牛B。

输出描述:

输出文件仅有一行,是绝对奶牛的数目。

输入样例:

3 3
1 2
2 1
2 3

输出样例:

1

数据范围:

对于30%的数据,有1<=N<=1000,1<=M<=5000;

对于100%的数据,有1<=N<=100000,1<=M<=500000。

-----------------------------------------------------------------

这道题我初次想要用拓扑排序做,发现会超时

然后改成Tarjan... 请自行搜索Tarjan求强连通分支

后来发现大数据会RE

用-Wl,--stack=134217728(设定栈大小为128M)就好了

所以是暴递归栈了

Egg Pain的我就Egg Pain地写了一个Egg Pain的递归栈模拟,纪念如下

不是很清晰,自行理解后再手打吧,抄袭不好。!

天呢,花了我一周调试~默一遍有助理解

#include <cstdio>
#include <algorithm>
struct Edge {
    int from, to;
    Edge* next;
};
const int MAXN = 100001, MAXM = 500001;
struct UFS {
    int father[MAXN], rank[MAXN], root(int);
    void initialize(int), plus(int, int);
    ~UFS();
};
struct Cell {
    int x;
    bool finished, first, visjto;
    Edge* j;
    void call();
};
int n, m, low[MAXN], dfn[MAXN], nowdfn, stk[MAXN], top, s[MAXN], cst;
bool vis[MAXN], ins[MAXN];
Edge* head[MAXN];
UFS ufs;
Cell cs[MAXN];
int main() {
    int cnt = 0, tmp;
    freopen("popular.in", "r", stdin);
    freopen("popular.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) {
        int s, t;
        Edge* tmp = new Edge;
        scanf("%d%d", &s, &t);
        tmp->from = s;
        tmp->to = t;
        tmp->next = head[s];
        head[s] = tmp;
    }
    ufs.initialize(n);
    for(int i = 1; i <= n; i++) {
        if(!vis[i]) {
            cst = 1;
            cs[cst].x = i;
            cs[cst].first = true;
            cs[cst].finished = false;
            while(cst != 0) {
                cs[cst].call();
                if(cs[cst].finished) {
                    cst--;
                }
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        for(Edge* j = head[i]; j != NULL; j = j->next) {
            if(ufs.root(i) != ufs.root(j->to)) {
                s[ufs.root(i)]++;
            }
        }
    }
    for(int i = 1; i <= n; i++) {
        if(ufs.root(i) == i && s[i] == 0) {
            cnt++;
            tmp = i;
        }
    }
    printf("%d\n", cnt == 1 ? ufs.rank[tmp] : 0);
    for(int i = 1; i <= n; i++) {
        while(head[i] != NULL) {
            Edge* tmp = head[i]->next;
            delete head[i];
            head[i] = tmp;
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
void UFS::initialize(int n) {
    for(int i = 1; i <= n; i++) {
        father[i] = i;
        rank[i] = 1;
    }
}
int UFS::root(int x) {
    return father[x] == x ? x : root(father[x]);
}
void UFS::plus(int x, int y) {
    father[y] = x;
    rank[x] += rank[y];
}
UFS::~UFS() {
    delete[] father;
    delete[] rank;
}
void Cell::call() {
    if(first) {
        nowdfn++;
        top++;
        dfn[x] = low[x] = nowdfn;
        ins[x] = vis[x] = true;
        stk[top] = x;
        j = head[x];
        first = false;
    }
    else {
        if(!visjto) {
            low[x] = std::min(low[x], low[j->to]);
        }
        if(ins[j->to]) {
            low[x] = std::min(low[x], dfn[j->to]);
        }
        j = j->next;
    }
    if(j == NULL) {
        if(low[x] == dfn[x]) {
            int f = stk[top];
            top--;
            if(f != x) {
                while(true) {
                    int i = stk[top];
                    top--;
                    ufs.plus(f, i);
                    if(i == x) {
                        break;
                    }
                }
            }
        }
        finished = true;
    }
    else {
        if(!vis[j->to]) {
            cst++;
            cs[cst].x = j->to;
            cs[cst].first = true;
            cs[cst].finished = false;
            visjto = false;
        }
        else {
            visjto = true;
        }
    }
}

 

总算把USACO的受欢迎奶牛做出来了

标签:

原文地址:http://www.cnblogs.com/dev-cpp/p/4237526.html

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