zoukankan      html  css  js  c++  java
  • P2763 试题库问题 (网络流 最大流)

    传送门

    解题思路

    比较简单的网络流,建图还是比较好想的。让源点向试题连流量为1的边,试题向所属类型连流量为1的边,类型向汇点连流量为需要此类试题的边。直接跑最大流,输出答案时找到那些满流的边所对的点。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    
    using namespace std;
    const int MAXN = 2005;
    const int MAXM = 50005;
    const int inf = 0x3f3f3f3f;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int k,n,head[MAXN],cnt=1,d[MAXN],sum,Sum;
    int S=0,T=2000,to[MAXM<<1],nxt[MAXM<<1],val[MAXM<<1];
    queue<int> Q;vector<int> ans[MAXN];
    
    inline void add(int bg,int ed,int w){
        to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;
    }
    
    bool bfs(){
        while(Q.size()) Q.pop();memset(d,0,sizeof(d));
        d[S]=1;Q.push(S);
        while(!Q.empty()){
            int x=Q.front();Q.pop();
            for(register int i=head[x];i;i=nxt[i]){
                int u=to[i];
                if(!d[u] && val[i]) {
                    d[u]=d[x]+1;Q.push(u);
                    if(u==T) return true;
                }
            }
        }
        return false;
    }
    
    int dinic(int x,int flow){
        if(x==T) return flow;
        int res=flow,k;
        for(register int i=head[x];i && res;i=nxt[i]){
            int u=to[i];
            if(d[u]==d[x]+1 && val[i]){
                k=dinic(u,min(flow,val[i]));
                if(!k) d[u]=0;
                val[i]-=k;val[i^1]+=k;res-=k;
            }
        }
        return flow-res;
    }
    
    int main(){
        k=rd(),n=rd();int x,y;
        for(int i=1;i<=k;i++)
            x=rd(),add(i,T,x),add(T,i,0),Sum+=x; 
        for(int i=1;i<=n;i++){
            x=rd();
            for(int j=1;j<=x;++j){
                y=rd();add(i+k,y,1);add(y,i+k,0);
            }
        }
        for(int i=1;i<=n;i++) add(S,i+k,1),add(i+k,S,0);
        while(bfs()) sum+=dinic(S,inf);
    //    cout<<sum<<endl;
        for(int i=1;i<=k;i++)
            for(int j=head[i];j;j=nxt[j]){
                if(to[j]==T) continue;
                if(!val[j^1]) ans[i].push_back(to[j]-k);
            }
        for(int i=1;i<=k;i++){
            printf("%d: ",i);
            for(int j=0;j<ans[i].size();j++) printf("%d ",ans[i][j]);
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    struts2-Action配置-通配符-DMI
    struts2中struts.xml和web.xml文件解析及工作原理
    IntelliJ IDEA 的Project structure说明
    深入理解乐观锁与悲观锁
    共享锁(S锁)和排它锁(X锁)
    乐观锁和悲观锁
    事务并发的可能问题与其解决方案
    Ehcache配置详解及CacheManager使用
    Hibernate一级缓存、二级缓存以及查询缓存的关系
    【转】Spring 的下载、安装和使用
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9786525.html
Copyright © 2011-2022 走看看