您的位置:首页 > 其它

poj 1904(强连通分量)

2012-07-29 10:41 357 查看
参考链接

http://nightelf.sinaapp.com/2011/poj-1904-%E7%A1%AE%E5%AE%9A%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%88%86%E5%8C%B9%E9%85%8D%E7%9A%84%E6%89%80%E6%9C%89%E5%8F%AF%E8%83%BD%E8%BE%B9.html

题意:n个王子和n个美女要进行配对,每个王子可以喜欢若干个美女,但只能匹配其一个美女,求解每个王子能配对的美女使得其他王子也能成功配对,按升序输出王子能匹配的美女的编号。数据已经给出一个完备匹配。

建图:王子到每个喜欢的美女连一条有向边,在给出的完备匹配中由美女到王子连接一条有向边。构图后简化一下描述就是:如果从 A 点出发,最终能回到 A 点(成环)则能够维持完全匹配的,因此求一次强连通分量,判断每个王子与其喜欢的美女是否在同一强连通分量即可。

View Code

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define N 5005
vector<int> g
;
stack<int> st;
int dfn
,low
,belg
,in
;
int c,indx;
void init(){
c=indx=1;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(belg,0,sizeof(belg));
memset(in,0,sizeof(in));
memset(g,0,sizeof(g));
}
void dfs(int u){
dfn[u]=low[u]=indx++;
in[u]=1;
st.push(u);
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(in[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
while(1){
int v=st.top();
st.pop();
in[v]=0;
belg[v]=c;
if(v==u)break;
}
c++;
}
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
init();
for(int i=1;i<=n;i++){
int m;
scanf("%d",&m);
while(m--){
int x;
scanf("%d",&x);
g[i].push_back(x+n);
}
}
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
g[x+n].push_back(i);
}
for(int i=1;i<=n;i++){
if(!dfn[i])dfs(i);
}
for(int i=1;i<=n;i++){
priority_queue<int ,vector<int> ,greater<int> > q;
for(int j=0;j<g[i].size();j++){
int v=g[i][j];
if(belg[i]==belg[v])q.push(v-n);
}
printf("%d",q.size());
while(!q.empty()){
printf(" %d",q.top());
q.pop();
}
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: