#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#define INF 1000000010
#define ll long long
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 1000
using namespace std;
bool m[210][210];
int p[210];
int find(int x){
if(x==p[x])return x;
p[x]=find(p[x]);
return p[x];
}
void _union(int a,int b){
int fa=find(a);
int fb=find(b);
p[fa]=fb;
}
vector<int> son[210];
bool vis[210];
bool level[210];
int d[210];
bool dp[210][210];
bool path[210][210];
bool sel[210];
int mp[210];
int main(){
//int t;
//cin>>t;
//while(t--){
memset(m,0,sizeof(m));
memset(vis,0,sizeof(vis));
memset(level,0,sizeof(level));
memset(dp,0,sizeof(dp));
memset(path,0,sizeof(path));
memset(sel,0,sizeof(sel));
memset(mp,0,sizeof(mp));
memset(d,0,sizeof(d));
int n;
cin>>n;
for(int i=1;i<=n;i++){
son[i].clear();
p[i]=i;
}
for(int i=1;i<=n;i++){
while(true){
int x;
cin>>x;
if(x==0)break;
m[i][x]=1;
}
}
//
bool ok=true;
int cnt=0;
for(int i=1;i<=n;i++){
//如果已经访问过则跳过
if(vis[i])continue;
//cout<<"------"<<endl;
cnt++;
mp[i]=cnt;
queue<int> que;
que.push(i);
level[i]=0;
while(!que.empty()){
int cur=que.front(); que.pop();
//cout<<cur<<"加入集合"<<endl;
if(level[cur]) d[cnt]++;
else d[cnt]--;
for(int j=1;j<=n;j++){
if(cur==j)continue;
if( !(m[cur][j]&&m[j][cur]) ){
//cout<<cur<<"属于"<<find(cur)<<","<<j<<"属于"<<find(j)<<endl;
if(find(cur)==find(j)){
if(level[cur]==level[j]){//产生了回路,无解
cout<<"No solution";//<<endl;
return 0;
ok=false;
break;
}else{
continue;
}
}
if(vis[j])continue;
que.push(j);
level[j]=!level[cur];
_union(j,i);
vis[j]=true;
}
}
}
//cout<<"集合"<<cnt<<"元素"<<d[cnt]<<"个"<<endl;
}
dp[0][105]=1;
for(int i=1;i<=cnt;i++){
for(int j=0;j<=209;j++){
if( dp[i-1][j-d[i]] ){
dp[i][j]=1;
path[i][j]=0;
}
if( dp[i-1][j+d[i]] ){
dp[i][j]=1;
path[i][j]=1;
}
//cout<<dp[i][j]<<" ";
}
//cout<<endl;
}
int tmp;
for(int i=0;;i++){
if(dp[cnt][105+i]||dp[cnt][105-i]){
tmp=i+105;
break;
}
}
//cout<<tmp<<endl;
for(int i=cnt;i>=1;i--){
sel[i]=path[i][tmp];
if(path[i][tmp]) tmp+=d[i];
else tmp-=d[i];
}
vector<int> g1;
vector<int> g2;
for(int i=1;i<=n;i++){
if( sel[mp[find(i)]]^level[i] ) g1.push_back(i);
else g2.push_back(i);
}
if(ok){
int s1=g1.size();
cout<<s1<<" ";
for(int i=0;i<s1;i++){
cout<<g1[i];cout<<" ";
}
cout<<endl;
int s2=g2.size();
cout<<s2<<" ";
for(int i=0;i<s2;i++){
cout<<g2[i];cout<<" ";
}
//cout<<endl;
}else{
cout<<"No solution"<<endl;
}
//if(t)cout<<endl;
//}
return 0;
}(未解决)uva1627/poj1112
最新推荐文章于 2025-05-18 23:23:50 发布
此博客展示了一段C++代码,用于解决集合划分问题。代码包含头文件引入、函数定义等,通过并查集、广度优先搜索等方法进行集合划分,最后根据条件输出划分结果,若产生回路则输出无解。
572

被折叠的 条评论
为什么被折叠?



