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

    题意

    有n道题,每个题有一些类别属性,先现出k个属性各需要的题数,一道题只能在一种类别。

    输出方案,没有则输出"No Solution!"

    (2 <=k<= 20, k<=n<= 1000)

    题解

    还是比较基础,把试题和属性分成两部分,试题与属性之间连边流量为1,源点与试题之间连边流量为1,属性与汇点连边流量为需要的题数。

    最后看最大流是否为总共需要的题数,输出方案则枚举看是否满流。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=1006;
    const int maxm=1000006;
    int n,m,k;
    int cnt=1,s,t,head[maxn];
    struct edge{
      int x,y,val,next;
    }e[maxm];
    
    template<class T>inline void read(T &x){
      x=0;char ch=getchar();
      while(!isdigit(ch)) ch=getchar();
      while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    }
    
    void add(int x,int y,int val){
      e[++cnt]=(edge){x,y,val,head[x]};
      head[x]=cnt;
    }
    
    int d[maxn];
    
    bool bfs(){
      queue<int> q;
      memset(d,0,sizeof(d));
      q.push(s);d[s]=1;
      while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=e[i].next){
          int y=e[i].y;
          if(e[i].val&&!d[y]){
            d[y]=d[x]+1;
            if(y==t) return true;
            q.push(y);
          }
        }
      }
      return false;
    }
    
    int dfs(int x,int flow){
      if(x==t) return flow;
      int rest=flow,k;
      for(int i=head[x];i;i=e[i].next){
        int y=e[i].y;
        if(d[y]==d[x]+1&&e[i].val){
          k=dfs(y,min(rest,e[i].val));
          if(!k) d[y]=0;
          e[i].val-=k;
          e[i^1].val+=k;
          rest-=k;
        }
      }
      return flow-rest;
    }
    
    int dinic(){
      int res=0;
      while(bfs()) res+=dfs(s,0x3f3f3f);
      return res;
    }
    
    int main(){
      scanf("%d%d",&k,&n);
      s=0;t=k+n+1;
      for(int i=1;i<=k;i++){
        int x;read(x);
        add(i+n,t,x);
        add(t,i+n,0);
        m+=x;
      }
      for(int i=1;i<=n;i++){
        add(s,i,1);
        add(i,s,0);
        int tot;read(tot);
        for(int j=1;j<=tot;j++){
          int x;read(x);
          add(i,x+n,1);
          add(x+n,i,0);
        }
      }
      int ans=dinic();
      if(ans!=m) {printf("No Solution!");return 0;}
      for(int i=n+1;i<=n+k;i++){
        printf("%d: ",i-n);
        for(int j=head[i];j;j=e[j].next)
         if(e[j].val) printf("%d ",e[j].y);
        putchar(10);
      }
    }
    View Code
  • 相关阅读:
    Git 版本更新(Windows下)
    Qt Quick 构建 Android app
    Android Studio更新到3.6.0 Gradle报错No cached version of com.android.tools.build:aapt2:3.2.0-alpha16-4748712 available for of...
    在自定义类中使用setMouseCallBack
    关于Qt 状态机
    C++ 新特性 移动构造函数和移动赋值
    关于Qt MetaObject connectSlotsByName
    Prototype 设计模式在框架中的应用
    关于设计模式
    如何提高Qt工程的编译速度
  • 原文地址:https://www.cnblogs.com/sto324/p/11353522.html
Copyright © 2011-2022 走看看