对着网上下的数据拍发现过不去,交上去就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; }