UVALive - 4287 Proving Equivalences

来源:互联网 发布:淮北微商自然知彼 编辑:程序博客网 时间:2024/06/16 23:53

1.题面

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2288

2.题意

给出若干个定理之间的证明关系,问你至少还需要几个证明,可以使得所有命题等价

3.思路

采用强连通分量缩点,随后找入度为0和出度为0的类型的点中较多的那个,当整个图为一个强连通分量的时候,答案为0

4.代码

/*****************************************************************    > File Name: acm.cpp    > Author: Uncle_Sugar    > Mail: uncle_sugar@qq.com    > Created Time: 2016/11/5 20:44:01*****************************************************************/# include <cstdio># include <cstring># include <cctype># include <cmath># include <cstdlib># include <climits># include <iostream># include <iomanip># include <set># include <map># include <vector># include <stack># include <queue># include <algorithm>using namespace std;const int size  = 5000 + 10; const int INF = INT_MAX>>1;typedef long long ll;/*Tarjan 算法模板,注意scc的编号从1开始*/const int MAXN = 20000 + 1000;const int MAXM = 50000 + 1000;int head[MAXN];struct Edge{int to, nxt;}edge[MAXM];int tot;void init(){tot = 0;memset(head, -1, sizeof(head));}void addedge(int from, int to){edge[tot].to = to; edge[tot].nxt = head[from]; head[from] = tot++;}int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;int stk[MAXN], top;int n, m;void dfs(int u){pre[u] = lowlink[u] = ++dfs_clock;/*这里不能改成dfs_clock++, 因为pre[v] == 0是v未被访问的标志*/stk[top++] = u;for (int e = head[u]; ~e; e = edge[e].nxt){int v = edge[e].to;if (!pre[v]){dfs(v);lowlink[u] = min(lowlink[u], lowlink[v]);}else if (!sccno[v]){lowlink[u] = min(lowlink[u], pre[v]);}}if (pre[u] == lowlink[u]){scc_cnt++;for (;;){int x = stk[--top];sccno[x] = scc_cnt;if (x == u) break;}}}void find_scc(int n){scc_cnt = dfs_clock = top = 0;memset(lowlink, 0, sizeof(lowlink));memset(pre, 0, sizeof(pre));memset(sccno, 0, sizeof(sccno));for (int i = 0; i < n; i++)if (!pre[i]) dfs(i);}int in[MAXN], out[MAXN];int main(){int T;scanf("%d", &T);while (T--){init();scanf("%d%d", &n, &m);while (m--){int a, b;scanf("%d%d", &a, &b);a--;b--;addedge(a, b);}find_scc(n);for (int i = 1; i <= scc_cnt; i++) in[i] = out[i] = 1;for (int i = 0; i < n; i++)for (int e = head[i]; ~e; e = edge[e].nxt){int v = edge[e].to;if (sccno[i] != sccno[v]){out[sccno[i]] = in[sccno[v]] = 0;}}int a = 0, b = 0;for (int i = 1; i <= scc_cnt; i++){if (in[i])  a++;if (out[i]) b++;}int ans = max(a, b);if (scc_cnt == 1) ans = 0;printf("%d\n", ans);}return 0;}


0 0
原创粉丝点击