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
  • 相关阅读:
    关于JDK和JRE的一些总结
    Jackson 格式化日期问题
    CentOS6.8安装mysql5.6
    CentOS6.8安装JDK1.7
    VMware NAT方式 CentOS 6.8配置静态IP
    CentOS6.8使用源码安装Git
    关于SourceTree License
    记录平时遇到的问题
    使用React-Router遇到的那些坑
    移动端响应式布局好文收集
  • 原文地址:https://www.cnblogs.com/sto324/p/11353522.html
Copyright © 2011-2022 走看看