poj 2186 Popular Cows(强连通)
2017-08-18 12:08
363 查看
题目链接:http://poj.org/problem?id=2186
[Submit] [Go Back] [Status]
[Discuss]
Home Page
Go
Back
To top
解析:本来想着用并查集写,仔细想想,并查集好像不能写,然后百度一下这个题,看到大牛用tarjan写,哇,好难啊,思路就是,先跑一边Tarjan模板,然后把每个强连通分量看成一个点,继续找出度为0的点,如果出度为0的点就一个,并且所有的牛都在强连通分量里,然后输出哪些牛在出度为0的强连通分量里(个数),否则0
借鉴大牛博客:http://blog.csdn.net/acm_cxq/article/details/52118237
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
const int N = 10009;
vector<int> mp
;
int n, m;
int cnt, tp, dfn
, low
, vis
, b
;
int out
;
stack<int> s;
void Tarjan(int u)
{
low[u] = dfn[u] = ++tp;
s.push(u);
vis[u] = 1;
for(int i = 0; i < mp[u].size(); i++)
{
int v = mp[u][i];
if(!dfn[v])
{
Tarjan(v);
if(low[v] < low[u]) low[u] = low[v];
}
else if(vis[v] && dfn[v] < low[u]) low[u] = dfn[v];
}
if(dfn[u] == low[u])
{
cnt++;
while(true)
{
int cur = s.top(); s.pop();
vis[cur] = 0;
b[cur] = cnt;
if(cur == u) break;
}
}
}
void solve()
{
cnt = tp = 0;
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(vis, 0, sizeof(vis));
memset(b, 0, sizeof(b));
for(int i = 1; i <= n; i++)
{
if(!dfn[i]) Tarjan(i);
}
}
int main()
{
int u, v;
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i <= n; i++) mp[i].clear();
while(m--)
{
scanf("%d%d", &u, &v);
mp[u].push_back(v);
}
solve();
memset(out, 0, sizeof(out));
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < mp[i].size(); j++)
{
int v = mp[i][j];
if(b[i] != b[v]) out[b[i]]++;
}
}
int v, tol = 0;
for(int i = 1; i <= cnt; i++)
{
if(!out[i])
{
tol++;
v = i;
}
}
for(int i = 1; i <= n; i++) if(!b[i]) tol = 0;
if(tol == 1)
{
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(b[i] == v) ans++;
}
printf("%d\n", ans);
}
else puts("0");
}
return 0;
}
Popular Cows
Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow. Input * Line 1: Two space-separated integers, N and M * Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular. Output * Line 1: A single integer that is the number of cows who are considered popular by every other cow. Sample Input 3 3 1 2 2 1 2 3 Sample Output 1 Hint Cow 3 is the only cow of high popularity. Source USACO 2003 Fall |
[Discuss]
Home Page
Go
Back
To top
解析:本来想着用并查集写,仔细想想,并查集好像不能写,然后百度一下这个题,看到大牛用tarjan写,哇,好难啊,思路就是,先跑一边Tarjan模板,然后把每个强连通分量看成一个点,继续找出度为0的点,如果出度为0的点就一个,并且所有的牛都在强连通分量里,然后输出哪些牛在出度为0的强连通分量里(个数),否则0
借鉴大牛博客:http://blog.csdn.net/acm_cxq/article/details/52118237
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
const int N = 10009;
vector<int> mp
;
int n, m;
int cnt, tp, dfn
, low
, vis
, b
;
int out
;
stack<int> s;
void Tarjan(int u)
{
low[u] = dfn[u] = ++tp;
s.push(u);
vis[u] = 1;
for(int i = 0; i < mp[u].size(); i++)
{
int v = mp[u][i];
if(!dfn[v])
{
Tarjan(v);
if(low[v] < low[u]) low[u] = low[v];
}
else if(vis[v] && dfn[v] < low[u]) low[u] = dfn[v];
}
if(dfn[u] == low[u])
{
cnt++;
while(true)
{
int cur = s.top(); s.pop();
vis[cur] = 0;
b[cur] = cnt;
if(cur == u) break;
}
}
}
void solve()
{
cnt = tp = 0;
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(vis, 0, sizeof(vis));
memset(b, 0, sizeof(b));
for(int i = 1; i <= n; i++)
{
if(!dfn[i]) Tarjan(i);
}
}
int main()
{
int u, v;
while(~scanf("%d%d", &n, &m))
{
for(int i = 0; i <= n; i++) mp[i].clear();
while(m--)
{
scanf("%d%d", &u, &v);
mp[u].push_back(v);
}
solve();
memset(out, 0, sizeof(out));
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < mp[i].size(); j++)
{
int v = mp[i][j];
if(b[i] != b[v]) out[b[i]]++;
}
}
int v, tol = 0;
for(int i = 1; i <= cnt; i++)
{
if(!out[i])
{
tol++;
v = i;
}
}
for(int i = 1; i <= n; i++) if(!b[i]) tol = 0;
if(tol == 1)
{
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(b[i] == v) ans++;
}
printf("%d\n", ans);
}
else puts("0");
}
return 0;
}
相关文章推荐
- POJ 2186 Popular Cows(强连通)
- POJ 2186 Popular Cows 强连通
- poj2186 Popular Cows --- 强连通
- 【POJ 2186 Popular Cows】+ 强连通
- POJ 2186 Popular Cows(初学强连通)
- POJ 2186 Popular Cows(强连通)
- POJ 2186 Popular Cows 强连通
- POJ 2186 Popular Cows(强连通)
- poj2186 Popular Cows(强连通)
- POJ 2186-Popular Cows:强连通分量问题
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows(强联通+缩点)
- poj 2186 Popular Cows
- poj - 2186 Popular Cows && poj - 2553 The Bottom of a Graph (强连通)
- POJ-2186 Popular Cows 强连通 + 缩点
- POJ 2186 Popular Cows 强连通分量(Kosaraju)
- POJ2186——Popular Cows
- poj 2186 Popular Cows
- poj 2186 Popular Cows(强连通分量缩点+dfs)
- poj_2186 Popular Cows(强连通分量)