0912 输入有锅的教训
实在是我太菜了啊啊啊
模拟赛的输入矩阵要注意啊,输入用字符串啊啊啊
排列的字典序就是按照大小啊啊啊
交换(swap)
题目描述
给定一个1~n的排列g,并给出一个n*n的01矩阵A(保证任取i,j属于[1,n]有Ai,j=Aj,i),你可以交换gi,gj当且仅当Ai,j=1。请输出能得到的字典序最小的排列。
输入格式
第一行一个整数n,表示排列的长度。
第二行n个整数依次给出排列g的元素。
接下来n行给出一个n*n的01矩阵A。
输出格式
一行n个用一个空格分开的整数,为能得到的字典序最小的排列。
样例输入
7
5 2 4 3 6 7 1
0001001
0000000
0000010
1000001
0000000
0010000
1001000
样例输出
1 2 4 3 6 7 5
样例解释
交换(g1,g7),可以证明它是能得到的字典序最小的排列。
数据范围和约定
对于40%的数据:n<=8
对于100%的数据:1<=n<=300, 保证任取i,j属于[1,n]有Ai,j=Aj,i。
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) #define ll long long using namespace std; const int N=305; namespace zjc{ int n,cnt,top,g[N],fa[N],a[N][N],tmp[N],c[N],id[N]; map<int,int> vis;char s[N]; inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} void work(){ scanf("%d",&n);cnt=n; rep(i,1,n) {scanf("%d",&g[i]);fa[i]=i;} rep(i,1,n){ scanf("%s",s); rep(j,0,n-1) if(s[j]=='1'){ int xx=find(i),yy=find(j+1); if(xx!=yy){fa[xx]=yy;--cnt;} } } rep(i,1,n){ int xx=find(i); if(!id[xx]) ++top,id[i]=top,id[xx]=top; else id[i]=id[xx]; } rep(i,1,cnt){ memset(tmp,0,sizeof tmp); int idx=0,cnt=0; rep(j,1,n) if(id[j]==i) tmp[++idx]=g[j]; sort(tmp+1,tmp+1+idx); idx=0; rep(j,1,n) if(id[j]==i) c[j]=tmp[++idx]; } rep(i,1,n) printf("%d ",c[i]); return; } } int main(){ freopen("swap.in","r",stdin); freopen("swap.out","w",stdout); zjc::work(); return 0; }