codevs1232
最大流dinic打法(这里用了当前弧优化)
#include<cstdio> #include<cstring> #include<cctype> #include<queue> #include<algorithm> #define inf 0x3ffffff #define maxn 505 using namespace std; int s,t,head[maxn],cur[maxn],cnt,dep[maxn]; struct data{int to,w,nex;}e[maxn<<2]; inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void addedge(int u,int v,int w){ e[cnt].to=v;e[cnt].w=w;e[cnt].nex=head[u];head[u]=cnt++; e[cnt].to=u;e[cnt].w=0;e[cnt].nex=head[v];head[v]=cnt++; } inline int bfs(){ queue<int>q; memset(dep,0,sizeof dep); dep[s]=1; q.push(s); while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];~i;i=e[i].nex){ int v=e[i].to; if(e[i].w>0 && dep[v]==0){ dep[v]=dep[u]+1; if(v==t)return 1; q.push(v); } } } return dep[t]!=0; } inline int dfs(int u,int flow){ if(u==t)return flow; int ans=0,x=0; for(int &i=cur[u];~i;i=e[i].nex){ int v=e[i].to; if(e[i].w>0 && dep[v]==dep[u]+1){ x=dfs(v,min(flow-ans,e[i].w)); e[i].w-=x;e[i^1].w+=x; ans+=x; if(ans==flow)return flow; } } if(ans==0)dep[u]=0; return ans; } inline int dinic(int n){ int ans=0; while(bfs()){ for(int i=0;i<=n;i++)cur[i]=head[i];ans+=dfs(s,inf); } return ans; } int main(){ int n,m;read(m);read(n); memset(head,-1,sizeof head); s=0,t=n+m+1; for(int i=1;i<=m;i++)addedge(s,i,1); for(int i=m+1;i<=n+m;i++)addedge(i,t,1); int u,v; while(1){read(u);read(v);if(u==-1 && v==-1)break;addedge(u,v,1);} int ans=dinic(t); printf("%d\n",ans); if(ans==0)return printf("No Solution!\n"),0; for(int i=m+1;i<=n+m;i++) for(int j=head[i];~j;j=e[j].nex)if(e[j].to!=t && e[j].w==1)printf("%d %d\n",e[j].to,i); return 0; }