对着网上下的数据拍发现过不去,交上去就1A了。。。。。。
看discuss才发现标程是错的。。。。。。。
根据14年的论文,A为n维向量的一组基,B中任意行向量属于Span(A),于是可以得出系数矩阵C,且C*A=B,A中行向量x能被B中行向量y替换当且仅当y的表示向量(C中的一个列向量)中x位置的系数不为0,于是C的转置即为二分图的邻接矩阵,问题转化为二分图最小字典序最大匹配
首先跑一遍匈牙利搞出一个最大匹配来
对于每个S点贪心地判断T点能否与它匹配
条件为T的匹配点能够走出一条到达S的增广路
(即linked[T]-Ti-Si-Tj---------T-S,这个过程和匈牙利差不多)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define mmt(a,v) memset(a,v,sizeof(a))
const int N=300+5;
typedef long long ll;
const int p=999911657;
ll qmul(ll a,ll b){
ll ans=1;
for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;
return ans;
}
ll inv(int x){return qmul(x,p-2);}
bool g[N][N];
int n;
struct matrix{
int a[N][N];
void clr(){mmt(a,0);}
void init(){rep(i,1,n)rep(j,1,n)scanf("%d",&a[i][j]);}
bool inverse(){
int d;
rep(k,1,n){
if(!a[k][k])return false;
d=inv(a[k][k]);
rep(i,1,n)if(i!=k)a[k][i]=1LL*a[k][i]*(p-d)%p;
rep(i,1,n)if(i!=k)a[i][k]=1LL*a[i][k]*d%p;
rep(i,1,n)if(i!=k)rep(j,1,n)if(j!=k)
(a[i][j]+=1LL*a[i][k]*a[k][j]%p*a[k][k]%p)%=p;
a[k][k]=d;
}
return true;
}
matrix operator * (const matrix &b)const{
static matrix c;c.clr();
rep(i,1,n)rep(j,1,n)rep(k,1,n)
(c.a[i][j]+=1LL*a[i][k]*b.a[k][j]%p)%=p;
return c;
}
void print(){
rep(i,1,n){
rep(j,1,n)printf("%d ",a[i][j]);
puts("");
}
}
}a,b,c;
void build(){rep(i,1,n)rep(j,1,n)g[i][j]=!!c.a[j][i];}
bool vis[N];
int linked[N];
bool match(int u){
rep(v,1,n)if(g[u][v]&&!vis[v]){
vis[v]=1;
if(!linked[v]||match(linked[v])){
linked[v]=u;
return true;
}
}
return false;
}
bool dfs(int u,int s){
if(u==s)return true;
rep(v,1,n)if(g[u][v]&&!vis[v]){
vis[v]=1;
if(dfs(linked[v],s)){
//printf("%d %d\n",u,v);
linked[v]=u;
return true;
}
}
return false;
}
int main(){
//freopen("a.in","r",stdin);
scanf("%d",&n);
a.init();b.init();
if(!a.inverse()){puts("NIE");return 0;}
c=b*a;build();
int ans=0;
rep(i,1,n){mmt(vis,0);ans+=match(i);}
if(ans!=n){puts("NIE");return 0;}
puts("TAK");
rep(i,1,n){
mmt(vis,0);
rep(j,1,n)g[i-1][j]=0;
rep(j,1,n)if(g[i][j]&&!vis[j]){
vis[j]=1;
if(linked[j]>=i&&dfs(linked[j],i)){
linked[j]=i;
printf("%d\n",j);
rep(k,1,n)g[k][j]=0;
break;
}
}
}
return 0;
}