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;
}

  

posted on 2013-01-26 11:19  夜->  阅读(234)  评论(0编辑  收藏  举报