zoukankan      html  css  js  c++  java
  • 洛谷P2319 [HNOI2006]超级英雄

    一开始是用二分图匹配(网络流)+二分做的,后来发现直接用匈牙利更简单

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define pii pair<int,int>
    #define X first
    #define Y second
    #define INF 0x7f7f7f7f
    #define MAXN 1000+10
    using namespace std;
    struct Edge{
        int from,to,cap,flow;
        Edge(int u=0,int v=0,int c=0,int f=0){
            from=u,to=v,cap=c,flow=f;
        }
    };
    struct Dinic{
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[MAXN<<1];
        int d[MAXN<<1];
        int b[MAXN<<1];
        int cur[MAXN<<1];
        void init(int n,int s,int t){
            this->n=n;
            this->s=s,this->t=t;
            edges.clear();
            for(int i=0;i<=n;i++){
                G[i].clear();
            }
        }
        void AddEdge(int x,int y,int cap){
            edges.push_back(Edge(x,y,cap,0));
            edges.push_back(Edge(y,x,0,0));
            m=edges.size();
            G[x].push_back(m-2);
            G[y].push_back(m-1);
        }
        bool BFS(){
            memset(b,0,sizeof(b));
            queue<int> q;
            d[s]=1;
            q.push(s);
            b[s]=1;
            while(!q.empty()){
                int x=q.front();q.pop();
                for(int i=0;i<G[x].size();i++){
                    Edge &e=edges[G[x][i]];
                    if(e.cap>e.flow&&!b[e.to]){
                        q.push(e.to);
                        b[e.to]=1;
                        d[e.to]=d[x]+1;
                    }
                }
            }
            return b[t];
        }
        int dfs(int x,int a){
            if(x==t||!a)return a;
            int flow=0,f;
            for(int &i=cur[x];i<G[x].size();i++){
                Edge &e=edges[G[x][i]];
                if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
                    edges[G[x][i]].flow+=f;
                    edges[G[x][i]^1].flow-=f;
                    flow+=f;
                    a-=f;
                    if(!a){
                        break;
                    }    
                }
            }
            return flow;
        }
        int Maxflow(){
            int flow=0;
            while(BFS()){
                memset(cur,0,sizeof(cur));
                flow+=dfs(s,INF);
            }
            return flow;
        }
    }D;
    int n,m;
    pii a[MAXN];
    int s[MAXN];
    void print(int x){
        for(int i=0;i<D.edges.size();i++){
            Edge &e=D.edges[i];
            if(e.flow>=1&&n+1<=e.to&&e.to<=n+x){
                s[e.to-n]=e.from;
            }
        }
        for(int i=1;i<=x;i++){
            printf("%d
    ",s[i]-1);
        }
    }
    void init(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a[i].X,&a[i].Y);
            a[i].X++,a[i].Y++;
        }
    }
    int check(int x){
        D.init(n+x+2,0,n+x+1);
        for(int i=1;i<=n;i++){
            D.AddEdge(0,i,1);
        }    
        for(int i=1;i<=x;i++){
            D.AddEdge(a[i].X,n+i,1);
            D.AddEdge(a[i].Y,n+i,1);
            D.AddEdge(n+i,n+x+1,1);
        }
        int ans=D.Maxflow();
        return (ans==x);
    }
    void solve(){
        int L=0,R=m;
        while(R-L>1){
            int mid=(L+R)/2;
            if(check(mid)){
                L=mid;
            }
            else{
                R=mid;
            }
        }
        if(check(R)){
            printf("%d
    ",R);
            print(R);
        }
        else if(check(L)){
            printf("%d
    ",L);
            print(L);
        }
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        init();
        solve();
        return 0;
    }
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define pii pair<int,int>
    #define X first
    #define Y second
    #define INF 0x7f7f7f7f
    #define MAXN 1000+10
    using namespace std;
    int n,m;
    int girl[MAXN],boy[MAXN];
    int used[MAXN];
    int a[MAXN][2];
    bool find(int x){
        for(int i=0;i<=1;i++){
            int y=a[x][i];
            if(!used[y]){
                used[y]=1;
                if(!girl[y]||find(girl[y])){
                    girl[y]=x;
                    boy[x]=y;
                    return 1;
                }    
            }
        }
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            x++,y++;
            a[i][0]=x,a[i][1]=y;
        }
        int ans=0;
        for(int i=1;i<=m;i++){
            memset(used,0,sizeof(used));
            if(find(i))
                ans++;
            else
                break;
        }
        printf("%d
    ",ans);
        for(int i=1;i<=ans;i++){
            printf("%d
    ",boy[i]-1);
        }
        return 0;
    }
  • 相关阅读:
    架构笔记七
    架构笔记六
    架构笔记五
    架构笔记四
    python2与python3的区别
    萌新VRTK学习(四)攀爬系统
    萌新VRTK学习(三)物体的抓取
    萌新VRTK学习(二)移动
    萌新VRTK学习(一)VRTK的配置
    C#委托事件随笔
  • 原文地址:https://www.cnblogs.com/w-h-h/p/8061156.html
Copyright © 2011-2022 走看看