记录编号 262956 评测结果 AAAAAAAAAA
题目名称 [Ural 1099] 工作安排 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 0.008 s
提交时间 2016-05-23 13:12:20 内存使用 4.29 MiB
显示代码纯文本
#include<cstdio>//O(n^3),神板子,码量不大 
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

const int maxl=99999999;
const int maxn=510; 
int n,m,i,j,s,v,match[maxn],ance[maxn*2][maxn],dist[maxn*2],ans,color;
//[1,n]代表S型点,[n+1,2*n]代表T型点
//ance[i][j]表示i的dist为j的祖先的原编号,hash[i][j]表示j(原编号)是否是i的祖先 
vector <int> l[maxn];
int hash[maxn*2][maxn];

int z[maxn*2],r;
void change(int x){
	ans++;
	for (int i=dist[x];i>0;i-=2){
		match[ance[x][i]]=ance[x][i-1];
		match[ance[x][i-1]]=ance[x][i];
	}
}
void extend(int x){
	int i,j,k,v=(x>n?x-n:x);
	if (x>n){//若为T型点 
		if (match[v]==0){//发现单身,增广 
			change(x);return;
		}
		k=match[v];
		if (hash[x][k]!=color&&dist[k]>dist[x]+1){//十分类似于dijsktra的松弛操作 
			dist[k]=dist[x]+1;
			for (j=1;j<=dist[x];j++)
				hash[k][ance[k][j]=ance[x][j]]=color;
			hash[k][ance[k][dist[k]]=k]=color;
			z[++r]=k;
		}
	}
	else
	for (i=0;i<(int)l[v].size();i++){//十分类似于dijsktra的松弛操作 
		k=n+l[v][i];
		if (hash[x][l[v][i]]!=color&&dist[k]>dist[x]+1){
			dist[k]=dist[x]+1;
			for (j=1;j<=dist[x];j++)
				hash[k][ance[k][j]=ance[x][j]]=color;
			hash[k][ance[k][dist[k]]=l[v][i]]=color;
			z[++r]=k;
		} 
	}
}
void bfs(int x){
	color=z[r=1]=x;						//初始化 
	for (int i=1;i<=2*n;i++) dist[i]=maxl;
	dist[x]=1;hash[x][x]=color;ance[x][1]=x;
	for (int i=1;i<=r;i++){			//广搜 
		extend(z[i]);
		if (match[x]!=0) return; 
	}
}

int main()
{
	freopen("WorkScheduling.in","r",stdin);
	freopen("WorkScheduling.out","w",stdout);
	scanf("%d",&n);
	while(~scanf("%d%d",&s,&v)){
		l[s].push_back(v);
		l[v].push_back(s);
	}
	for (i=1;i<=n;i++)
	if (match[i]==0)
		bfs(i);
	printf("%d\n",ans*2);
	for (i=1;i<=n;i++)
	if (match[i]!=0&&i<match[i])
		printf("%d %d\n",i,match[i]);
	return 0;
}