网络流24题 ——补坑计划

之前刷过一段时间的网络流 是时候回来复习一波辣 慢慢补咯QAQ

51nod 2006 飞行员配对(二分图最大匹配)

注意反向边从1开始QAQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=257,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,S,T; 
int d[M],ans;
int first[M],cnt=1,cur[M];
struct node{int to,next,flow;}e[M*M];
void ins(int a,int b,int flow){e[++cnt]=(node){b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
queue<int>q;
int bfs(){
    memset(d,-1,sizeof(d));
    q.push(S); d[S]=0;
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now);
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||!a) return a;
    int flow=0,f;
    for(int& i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){
            e[i].flow-=f;
            e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int main()
{
    n=read(); m=read();
    S=0; for(int i=1;i<=n;i++) insert(S,i,1);
    T=m+1; for(int i=n+1;i<=m;i++) insert(i,T,1);
    int x=read(),y=read();
    while(x!=-1&&y!=-1) insert(x,y,1),x=read(),y=read();
    while(bfs()){
        for(int i=S;i<=T;i++) cur[i]=first[i];
        ans+=dfs(S,inf);
    }
    if(ans) printf("%d\n",ans);
    else printf("No Solution!\n");
    return 0;
}
View Code

 当然poweroj要求输出方案 就多两行 题目传送门

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int M=257,inf=0x3f3f3f3f;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,S,T; 
int d[M],ans;
int first[M],cnt=1,cur[M];
struct node{int from,to,next,flow;}e[M*M];
void ins(int a,int b,int flow){e[++cnt]=(node){a,b,first[a],flow}; first[a]=cnt;}
void insert(int a,int b,int flow){ins(a,b,flow); ins(b,a,0);}
queue<int>q;
int bfs(){
    memset(d,-1,sizeof(d));
    q.push(S); d[S]=0;
    while(!q.empty()){
        int x=q.front(); q.pop();
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(e[i].flow&&d[now]==-1) d[now]=d[x]+1,q.push(now);
        }
    }
    return d[T]!=-1;
}
int dfs(int x,int a){
    if(x==T||!a) return a;
    int flow=0,f;
    for(int& i=cur[x];i;i=e[i].next){
        int now=e[i].to;
        if(d[now]==d[x]+1&&(f=dfs(now,min(a,e[i].flow)))>0){
            e[i].flow-=f;
            e[i^1].flow+=f;
            flow+=f;
            a-=f; if(!a) break;
        }
    }
    return flow;
}
int sum;
struct Ans{int x,y;}Q[M*M];
bool cmp(Ans a,Ans b){return a.x<b.x;}
int main()
{
    n=read(); m=read();
    S=0; for(int i=1;i<=n;i++) insert(S,i,1);
    T=m+1; for(int i=n+1;i<=m;i++) insert(i,T,1);
    int k=cnt;
    int x=read(),y=read();
    while(x!=-1&&y!=-1) insert(x,y,1),x=read(),y=read();
    while(bfs()){
        for(int i=S;i<=T;i++) cur[i]=first[i];
        ans+=dfs(S,inf);
    }
    if(ans){
        printf("%d\n",ans);
        for(int i=k+1;i<=cnt;i+=2) if(!e[i].flow) printf("%d %d\n",e[i].from,e[i].to);
    }
    else printf("No Solution!\n");
    return 0;
}
View Code

 

posted @ 2017-08-17 14:18  友人Aqwq  阅读(207)  评论(0编辑  收藏  举报