记录编号 409212 评测结果 AAAAAAAAAA
题目名称 [Ural 1099] 工作安排 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 0.123 s
提交时间 2017-05-27 06:06:58 内存使用 1.04 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=255,p=1000000007;
void Gauss(int[][maxn],int[][maxn],int);
void eliminate(int,int);
int qpow(int,int);
int A[maxn][maxn],B[maxn][maxn],t[maxn][maxn],id[maxn],a[maxn];
bool girl[maxn]={false},row[maxn]={false},col[maxn]={false};
int n;
int main(){
	freopen("WorkScheduling.in","r",stdin);
	freopen("WorkScheduling.out","w",stdout);
	srand(23333333);
	scanf("%d",&n);
	int x,y;
	while(scanf("%d%d",&x,&y)==2){
		A[x][y]=rand()%p;
		A[y][x]=-A[x][y];
	}
	for(int i=1;i<=n;i++)id[i]=i;
	memcpy(t,A,sizeof(t));
	Gauss(A,NULL,n);
	int m=n;
	n=0;
	for(int i=1;i<=m;i++)if(A[id[i]][id[i]])a[++n]=i;
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)A[i][j]=t[a[i]][a[j]];
	Gauss(A,B,n);
	printf("%d\n",n);
	for(int i=1;i<=n;i++)if(!girl[a[i]])
		for(int j=i+1;j<=n;j++)if(!girl[a[j]]&&t[a[i]][a[j]]&&B[j][i]){
			printf("%d %d\n",a[i],a[j]);
			girl[a[i]]=girl[a[j]]=true;
			eliminate(i,j);
			eliminate(j,i);
			break;
		}
	return 0;
}
void Gauss(int A[][maxn],int B[][maxn],int n){
	if(B){
		memset(B,0,sizeof(t));
		for(int i=1;i<=n;i++)B[i][i]=1;
	}
	for(int i=1;i<=n;i++){
		if(!A[i][i]){
			for(int j=i+1;j<=n;j++)if(A[j][i]){
				swap(id[i],id[j]);
				for(int k=i;k<=n;k++)swap(A[i][k],A[j][k]);
				if(B)for(int k=1;k<=n;k++)swap(B[i][k],B[j][k]);
				break;
			}
			if(!A[i][i])continue;
		}
		int inv=qpow(A[i][i],p-2);
		for(int j=1;j<=n;j++)if(i!=j&&A[j][i]){
			int t=(long long)A[j][i]*inv%p;
			for(int k=i;k<=n;k++)if(A[i][k])A[j][k]=(A[j][k]-(long long)t*A[i][k])%p;
			if(B)for(int k=1;k<=n;k++)if(B[i][k])B[j][k]=(B[j][k]-(long long)t*B[i][k])%p;
		}
	}
	if(B)for(int i=1;i<=n;i++){
		int inv=qpow(A[i][i],p-2);
		for(int j=1;j<=n;j++)if(B[i][j])B[i][j]=(long long)B[i][j]*inv%p;
	}
}
void eliminate(int r,int c){
	row[r]=col[c]=true;
	int inv=qpow(B[r][c],p-2);
	for(int i=1;i<=n;i++)if(!row[i]&&B[i][c]){
		int t=(long long)B[i][c]*inv%p;
		for(int j=1;j<=n;j++)if(B[r][j])B[i][j]=(B[i][j]-(long long)t*B[r][j])%p;
	}
}
int qpow(int a,int b){
	int ans=1;
	for(;b;b>>=1,a=(long long)a*a%p)if(b&1)ans=(long long)ans*a%p;
	return ans;
}