【题解】
二分图最大匹配的模板题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #define N 1010 4 #define rg register 5 using namespace std; 6 int n,m,tot,ans,T,last[N],v[N],from[N]; 7 struct edge{ 8 int to,pre; 9 }e[N*N]; 10 struct rec{ 11 int x,y; 12 }a[N]; 13 inline int read(){ 14 int k=0,f=1; char c=getchar(); 15 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 16 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 17 return k*f; 18 } 19 int dfs(int x){ 20 for(rg int i=last[x],to;i;i=e[i].pre)if(v[to=e[i].to]!=T){ 21 v[to]=T; 22 if(!from[to]||dfs(from[to])){ 23 from[to]=x; 24 return 1; 25 } 26 } 27 return 0; 28 } 29 inline bool cmp(rec a,rec b){return a.x<b.x;} 30 int main(){ 31 n=read(); m=read(); 32 while(1){ 33 int x=read(),y=read(); 34 if(x==-1&&y==-1) break; 35 e[++tot]=(edge){y,last[x]}; last[x]=tot; 36 } 37 for(rg int i=1;i<=m;i++) ++T,ans+=dfs(i); 38 if(ans){ 39 printf("%d ",ans); tot=0; 40 for(rg int i=1;i<=m;i++) if(from[i]) a[++tot]=(rec){from[i],i}; 41 sort(a+1,a+1+tot,cmp); 42 for(rg int i=1;i<=tot;i++) printf("%d %d ",a[i].x,a[i].y); 43 } 44 else puts("No solution"); 45 return 0; 46 }