POJ 1904 King's Quest 强连通分量+二分图增广判定
Posted shuguangzw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1904 King's Quest 强连通分量+二分图增广判定相关的知识,希望对你有一定的参考价值。
http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html
这位神说的很好
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <string> #include <stack> #include <vector> #include <map> #include <queue> #include <algorithm> #include <utility> using namespace std; typedef long long LL; const int N=4e3+5; const int INF=0x3f3f3f3f; struct Edge { int v,next; } edge[N*N]; int head[N],tot,n; void add(int u,int v) { edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++; } stack<int>s; bool instack[N],mp[N/2+5][N/2+5]; int dfn[N],low[N],clk,cnt,bel[N]; void targin(int u) { dfn[u]=low[u]=++clk; instack[u]=true; s.push(u); for(int i=head[u]; ~i; i=edge[i].next) { int v=edge[i].v; if(!dfn[v]) { targin(v); low[u]=min(low[u],low[v]); } else if(instack[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { ++cnt; int k; do { k=s.top(); s.pop(); instack[k]=false; bel[k]=cnt; } while(k!=u); } } vector<int>g; int main() { scanf("%d",&n); memset(head,-1,sizeof(head)); for(int i=1; i<=n; ++i) { int k; scanf("%d",&k); for(int j=0; j<k; ++j) { int v; scanf("%d",&v); mp[i][v]=true; add(i,v+n); } } for(int i=1; i<=n; ++i) { int u; scanf("%d",&u); add(u+n,i); } for(int i=1; i<=n; ++i) if(!dfn[i])targin(i); for(int i=1; i<=n; ++i) { g.clear(); int k1=bel[i],k2; for(int j=n+1; j<=n+n; ++j) { k2=bel[j]; if(!mp[i][j-n]||k1!=k2)continue; g.push_back(j-n); } printf("%d",g.size()); for(int j=0; j<g.size(); ++j) printf(" %d",g[j]); printf("\\n"); } return 0; }
以上是关于POJ 1904 King's Quest 强连通分量+二分图增广判定的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1904 King's Quest 强连通分量+二分图增广判定
King's Quest POJ - 1904(强连通分量)
POJ3682 King Arthur's Birthday Celebration