bzoj 3168: [Heoi2013]钙铁锌硒维生素 线性代数+二分图匹配
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mod 999983 #define maxn 302 #define F(x,y) for(int x=1;x<=y;x++) using namespace std; typedef long long ll; ll a[maxn][maxn]; ll b[maxn][maxn]; int u[maxn],v[maxn]; ll c[maxn][maxn]; int n; int rec[maxn],ans[maxn]; ll inv[mod]; int map[maxn][maxn]; void fail() { puts("NIE"); exit(0); } void gauss(){ F(i,n)c[i][i]=1; F(i,n){ F(j,n)if(a[i][j]&&!v[j]){ u[i]=j; v[j]=i; break; } ll w=inv[a[i][u[i]]]; for(int j=i;j<=i;j++)F(z,n)a[j][z]=(a[j][z]*w)%mod,c[j][z]=(c[j][z]*w)%mod; F(j,n)if(i!=j){ w=mod-a[j][u[i]]; F(z,n){ a[j][z]=(a[j][z]+w*a[i][z])%mod; c[j][z]=(c[j][z]+w*c[i][z])%mod; } } } } int l[maxn],vis[maxn],num; bool dfs(int x,int now){ if(x<=now)return 0; for(int i=1;i<=n;i++)if(map[x][i]&&!vis[i]){ vis[i]=1; if(!l[i]||dfs(l[i],now)){ l[i]=x; return 1; } } return 0; } int main(){ inv[1]=1; for(int i=2;i<mod;i++) inv[i]=(ll)inv[mod%i]*(mod-mod/i)%mod; cin>>n; F(i,n)F(j,n)scanf("%lld",&a[i][j]); F(i,n)F(j,n)scanf("%lld",&b[i][j]); gauss(); F(i,n){ ll tt; F(j,n){ tt=0; F(k,n)tt=(tt+b[j][k]*c[u[k]][i])%mod; if(tt)map[i][j]=1; } } num=0; for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); if(dfs(i,0))num++; } if(num!=n)fail(); F(i,n){ F(j,n)if(map[i][j]&&l[j]>i){ int ff=0,bf; F(z,n)rec[z]=l[z]; F(z,n)if(l[z]==i){ ff=z; break; } l[ff]=0; bf=l[j]; l[j]=i; memset(vis,0,sizeof(vis)); if(dfs(bf,i)){ ans[i]=j; break; }else{ F(z,n)l[z]=rec[z]; } }else{ if(l[j]==i){ ans[i]=j; break; } } } puts("TAK"); F(i,n) printf("%d\n",ans[i]); }