您的位置:首页 > 其它

Codeforces 500B New Year Permutation

2016-08-13 11:03 330 查看
http://codeforces.com/problemset/problem/500/B

Floyd算法

先用Floyd把各个位置之间能直接或间接交换的找出来,再按从前往后遍历,放入尽可能小的数字。

/*
内存2404KB,用时46ms。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#define fi first
#define se second
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
//head
const int maxn = 305;
int a[maxn][maxn];
int pos[maxn];
int p[maxn];
bool vis[maxn];
int n;

void Floyd()
{
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
a[i][j] |= a[i][k] & a[k][j];
}

int main()
{
while(scanf("%d",&n)==1)
{
memset(vis, false, sizeof(vis));
for(int i=1; i<=n; i++)
{
scanf("%d",&p[i]);
pos[p[i]] = i;
}
getchar();
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
char ch;
scanf("%c",&ch);
a[i][j] = int(ch - '0');
}
getchar();
}
Floyd();
for(int i=1; i<=n; i++)//position
for(int j=1; j<=n; j++)//number
if(a[i][pos[j]]==1 && !vis[j])
{
//printf("%d %d\n",i,pos[j]);
vis[j] = true;
int tmp = pos[j];
pos[j] = i;
pos[p[i]] = tmp;
p[tmp] = p[i];
p[i] = j;
break;
}
for(int i=1; i<n; i++)
printf("%d ",p[i]);
printf("%d\n",p
);
}
return 0;
}


并查集写法

和Floyd类似,把互相能换位置的数字放入相同的集合,再对各个位置查询和自己在同一集合中的尽量小的数。

/*
内存2036KB,用时15ms。
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#define fi first
#define se second
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
//head
const int maxn = 305;
int fa[maxn];
int p[maxn];
bool vis[maxn];
char s[maxn];

int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}

int main()
{
int n;
while(scanf("%d",&n)==1)
{
memset(vis, false, sizeof(vis));
for(int i=1; i<=n; i++)
{
scanf("%d",&p[i]);
fa[i] = i;
}
for(int i=1; i<=n; i++)
{
scanf("%s",s);
for(int j=0; j<n; j++)
if(s[j]=='1')
fa[find(p[j+1])] = find(p[i]);
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(!vis[j] && find(j)==find(p[i]))
{
p[i] = j;
vis[j] = true;
break;
}
for(int i=1; i<n; i++)
printf("%d ",p[i]);
//printf("%d ",find(i));
printf("%d\n",p
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: