http://acm.timus.ru/problem.aspx?space=1&num=1339
对于喜欢的关系看做是一个单向边 这样整个图 有一些单个的点 也会有一些长链 也会有一些环
对于长链 从头开始进行配对 最后一个可能剩下变成单个点
然后对环进行配对 一定正好是偶数
然后单个点进行配对
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<map> #include<vector> #include<stack> #include<set> #include<map> #include<queue> #include<algorithm> #include<cmath> #define LL long long #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int INF=0x3f3f3f3f; const int N=500005; bool beliked[N]; int with[N]; int f[N]; void init(int n) { for(int i=1;i<=n;++i) { cin>>f[i]; if(f[i]==0) continue; f[i]+=n;beliked[f[i]]=true; } for(int i=n+1;i<=2*n;++i) { cin>>f[i]; if(f[i]==0) continue; beliked[f[i]]=true; } } void dfs(int x) { int k=f[x]; with[x]=k; with[k]=x; if(f[k]!=0&&with[f[k]]==0) dfs(f[k]); } int main() { //freopen("data.in","r",stdin); int n; while(cin>>n) { memset(beliked,false,sizeof(beliked)); memset(with,0,sizeof(with)); init(n); for(int i=1;i<=2*n;++i) if(!beliked[i]&&f[i]!=0) dfs(i); for(int i=1;i<=2*n;++i) if(f[i]!=0&&with[i]==0) dfs(i); int k=n+1; for(int i=1;i<=n;++i) { if(with[i]>0) cout<<(with[i]-n)<<" "; else { while(with[k]>0) ++k; cout<<((k++)-n)<<" "; } } } return 0; }