标签:des style blog http color io os ar for
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 8904 | Accepted: 3689 |
Description
Input
Output
Sample Input
3 3 1 3 2 3 3 1 2 1 1 2 0
Sample Output
1 3 2
题目意思:
给一个n个结点,m条边的有向图,若一个点所能到达的其他点都能到达该点或一个点不能到达其他点,那么该点为sink,从小到达输出sink。
思路:
这个题难在翻译上,特别是我这四级考了两次才过的人T-T,看懂了就很水了,先用tarjan缩点分块,然后求出没有出度的块的点标记下来,最后排序输出就行了。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 #include <queue> 7 #include <stack> 8 using namespace std; 9 10 #define N 5005 11 int n, m; 12 vector<int>ve[N]; 13 int low[N], dfn[N], dfn_clock; 14 int in[N], out[N], instack[N], a[N], b[N]; 15 int cnt; 16 stack<int>st; 17 18 void init(){ 19 int i, j; 20 while(!st.empty()) st.pop(); 21 22 for(i=0;i<=n;i++){ 23 ve[i].clear();instack[i]=1; 24 } 25 memset(dfn,0,sizeof(dfn)); 26 memset(in,0,sizeof(in)); 27 memset(out,0,sizeof(out)); 28 } 29 30 void tarjan(int u){ 31 int i, j, v; 32 dfn[u]=low[u]=dfn_clock++; 33 st.push(u); 34 for(i=0;i<ve[u].size();i++){ 35 v=ve[u][i]; 36 if(!dfn[v]){ 37 tarjan(v); 38 low[u]=min(low[u],low[v]); 39 } 40 else if(instack[v]){ 41 low[u]=min(low[u],dfn[v]); 42 } 43 } 44 if(low[u]==dfn[u]){ 45 cnt++; 46 while(1){ 47 v=st.top();st.pop(); 48 a[v]=cnt;instack[v]=0; 49 if(v==u) break; 50 } 51 } 52 } 53 54 main() 55 { 56 int i, j, k; 57 int x, y; 58 while(scanf("%d",&n)==1&&n){ 59 scanf("%d",&m); 60 init(); 61 while(m--){ 62 scanf("%d %d",&x,&y); 63 ve[x].push_back(y); 64 } 65 dfn_clock=1;cnt=0; 66 for(i=1;i<=n;i++){ 67 if(!dfn[i]) 68 tarjan(i); 69 } 70 for(i=1;i<=n;i++){ 71 for(j=0;j<ve[i].size();j++){ 72 x=ve[i][j]; 73 if(a[x]!=a[i]){ 74 out[a[i]]++;in[a[x]]++; 75 } 76 } 77 } 78 k=0; 79 for(i=1;i<=n;i++){ 80 if(!out[a[i]]){ 81 b[k++]=i; 82 } 83 } 84 sort(b,b+k); 85 printf("%d",b[0]); 86 for(i=1;i<k;i++) printf(" %d",b[i]); 87 cout<<endl; 88 } 89 }
标签:des style blog http color io os ar for
原文地址:http://www.cnblogs.com/qq1012662902/p/4007348.html