标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 29773 | Accepted: 12080 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
题意:
有n头牛,每头牛之间有仰慕关系。有m个关系对(A,B)表示A仰慕B,并且具有传递性。 问被所有除了本身以外的牛仰慕的牛有几个。
思路:
由于强连通中的牛都是相互仰慕的,所以可以先缩点。然后判断出度为0的个数,如果出度为0,说明这个牛肯定是被人仰慕的。如果出度为0
的点个数大于1,说明是不可能的。因为着几个点之间不会有关系。 如果出度为1的点个数只有1个,说明存在这样的牛,并且就是这个缩点后该带点表示的个数。
/* * Author: sweat123 * Created Time: 2016/6/25 13:45:46 * File Name: main.cpp */ #include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<string> #include<vector> #include<cstdio> #include<time.h> #include<cstring> #include<iostream> #include<algorithm> #define INF 1<<30 #define MOD 1000000007 #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pi acos(-1.0) using namespace std; const int MAXN = 10010; struct node{ int from; int to; int next; }edge[MAXN*10]; int pre[MAXN],vis[MAXN],dfn[MAXN],low[MAXN],n,m,ind; int f[MAXN],siz[MAXN],num,dep,out[MAXN]; stack<int>s; void add(int x,int y){ edge[ind].from = x; edge[ind].to = y; edge[ind].next = pre[x]; pre[x] = ind ++; } void dfs(int rt){ dfn[rt] = low[rt] = ++dep; vis[rt] = 1; s.push(rt); for(int i = pre[rt]; i != -1; i = edge[i].next){ int t = edge[i].to; if(!dfn[t]){ dfs(t); low[rt] = min(low[rt],low[t]); } else if(vis[t]){ low[rt] = min(low[rt],dfn[t]); } } if(low[rt] == dfn[rt]){ ++num; while(!s.empty()){ int tp = s.top(); s.pop(); vis[tp] = 0; f[tp] = num; siz[num] ++; if(tp == rt)break; } } } void setcc(){ num = 0; dep = 0; memset(out,0,sizeof(out)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); for(int i = 1; i <= n; i++){ if(!dfn[i]){ dfs(i); } } memset(pre,-1,sizeof(pre)); int ret = ind; for(int i = 0; i < ret; i++){ int x = f[edge[i].from]; int y = f[edge[i].to]; if(x == y)continue; add(x,y); out[x] ++; } int ans = 0; int flag = 0; for(int i = 1; i <= num; i++){ if(out[i] == 0){ if(flag == 1){flag = 2;break;} flag = 1; ans += siz[i]; } } if(flag == 2){ ans = 0; } printf("%d\n",ans); } int main(){ while(~scanf("%d%d",&n,&m)){ ind = 0; memset(pre,-1,sizeof(pre)); while(!s.empty())s.pop(); memset(f,-1,sizeof(f)); memset(siz,0,sizeof(siz)); for(int i = 1; i <= m; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); } setcc(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/sweat123/p/5616271.html