(寒假集训)Reordering the Cows

Reordering the Cows

时间限制: 1 Sec  内存限制: 64 MB
提交: 18  解决: 7
[提交][状态][讨论版]

题目描述

Farmer John's N cows (1 <= N <= 100), conveniently numbered 1..N, are standing in a row.  Their ordering is described by an array A, where A(i) is the number of the cow in position i.  Farmer John wants to rearrange
them into a different ordering for a group photo, described by an array B, where B(i) is the number of the cow that should end up in position i.

For example, suppose the cows start out ordered as follows:
A = 5 1 4 2 3
and suppose Farmer John would like them instead to be ordered like this:
B = 2 5 3 1 4

To re-arrange themselves from the "A" ordering to the "B" ordering, the cows perform a number of "cyclic" shifts.  Each of these cyclic shifts begins with a cow moving to her proper location in the "B" ordering, displacing another cow, who then moves to her proper location, displacing another cow, and so on, until eventually a cow ends up in the position initially occupied by the first cow on the cycle.  For example, in the ordering above, if we start a cycle with cow 5, then cow 5 would move to position 2, displacing cow 1, who moves to position 4, displacing cow 2, who moves to position 1, ending the cycle.  The cows keep performing cyclic shifts until every cow eventually ends up in her proper location in the "B" ordering.  Observe that each cow participates in exactly one cyclic shift, unless she occupies the same position in the "A" and "B" orderings.

Please compute the number of different cyclic shifts, as well as the length of the longest cyclic shift, as the cows rearrange themselves.

输入

* Line 1: The integer N.
* Lines 2..1+N: Line i+1 contains the integer A(i).
* Lines 2+N..1+2N: Line 1+N+i contains the integer B(i).

输出

* Line 1: Two space-separated integers, the first giving the number of cyclic shifts and the second giving the number cows involved in the longest such shift.  If there are no cyclic shifts,output -1 for the second number.

样例输入

5
5
1
4
2
3
2
5
3
1
4

样例输出

2 3

提示

There are two cyclic shifts, one involving cows 5, 1, and 2, and the other involving cows 3 and 4.

【分析】这一题我想复杂了,其实循环也可以做,我使用并查集找环的。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
typedef long long ll;
using namespace std;
const int N = 205;
const int M = 24005;
int  n,m,k,l,tot=0;
int a[N],b[N];
int parent[N],pre[N],vis[N];
int mark[N][N];
vector<int>vec[N],ans[N*N];
int Find(int x)
{
    if(parent[x]!=x)parent[x]=Find(parent[x]);
    return parent[x];
}
void Union(int x,int y)
{
    x=Find(x);
    y=Find(y);
    if(x==y)return;
    else parent[y]=x;
}
void bfs(int s,int t)
{
    met(vis,0);
    met(pre,0);
    queue<int>q;
    q.push(s);
    vis[s]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        if(u==t)return;
        for(int i=0; i<vec[u].size(); i++)
        {
            int v=vec[u][i];
            if(!vis[v])
            {
                pre[v]=u;
                vis[v]=1;
                q.push(v);
            }
        }
    }
}
int main()
{
    int u,v;
    for(int i=0; i<N; i++)parent[i]=i;
    scanf("%d",&n);
    for(int i=1; i<=n; i++)scanf("%d",&a[i]);
    for(int i=1; i<=n; i++)scanf("%d",&b[i]);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(a[i]==b[j]&&!mark[i][j])
            {
                mark[i][j]=1;
                u=i;v=j;
                int x=Find(u);
                int y=Find(v);
                if(x==y)
                {
                    bfs(u,v);
                    ans[++tot].push_back(v);
                    while(pre[v])
                    {
                        ans[tot].pb(pre[v]);
                        v=pre[v];
                    }
                }
                else
                {
                    vec[u].pb(v);
                    vec[v].pb(u);
                    Union(u,v);
                }
                break;
            }
        }
    }
    int aans=0,sum=0;
    for(int i=1; i<=tot; i++)
    {
        if(ans[i].size()>1){
            sum++;
            if(ans[i].size()>aans)aans=ans[i].size();
        }
}
if(sum!=0)printf("%d %d\n",sum,aans);
else printf("%d -1\n",sum);
return 0;
}

 

posted @ 2017-01-12 20:13  贱人方  阅读(573)  评论(0编辑  收藏  举报