zoukankan      html  css  js  c++  java
  • 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

    【题意】

      假设一个试题库中有 n 道试题。 每道试题都标明了所属类别。 同一道题可能有多个类别属性。现要从题库中抽取 m 道题组成试卷。并要求试卷包含指定类型的试题。 试设计一个
    满足要求的组卷算法。

    输入文件示例
    input.txt
    3 15
    3 3 4
    2 1 2
    1 3
    1 3
    1 3
    1 3
    3 1 2 3
    2 2 3
    2 1 3
    1 2
    1 2
    2 1 2
    2 1 3
    2 1 2
    1 1
    3 1 2 3

    输出文件示例
    output.txt
    1: 1 6 8
    2: 7 9 10
    3: 2 3 4 5

    【分析】

      二分图多重匹配, 应该是指 点可以选w[i]次,边只能选一次吧。

      这样就不能用匈牙利了吧。。[咦~~好像也可以,就是要记录所有w次匹配的是谁 然后枚举

      也可以把点拆开,然后做匈牙利,(有空再试试)

      嗯,最大流建边就很简单啦,那就不说了。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 using namespace std;
      9 #define Maxn 1010
     10 #define INF 0xfffffff
     11 
     12 struct node
     13 {
     14     int x,y,f,o,next;
     15 }t[Maxn*1010];int len;
     16 int first[Maxn];
     17 
     18 int mymin(int x,int y) {return x<y?x:y;}
     19 int mymax(int x,int y) {return x>y?x:y;}
     20 
     21 void ins(int x,int y,int f)
     22 {
     23     t[++len].x=x;t[len].y=y;t[len].f=f;
     24     t[len].next=first[x];first[x]=len;t[len].o=len+1;
     25     t[++len].x=y;t[len].y=x;t[len].f=0;
     26     t[len].next=first[y];first[y]=len;t[len].o=len-1;
     27 }
     28 
     29 int st,ed;
     30 queue<int > q;
     31 int dis[Maxn];
     32 bool bfs()
     33 {
     34     while(!q.empty()) q.pop();
     35     memset(dis,-1,sizeof(dis));
     36     q.push(st);dis[st]=0;
     37     while(!q.empty())
     38     {
     39         int x=q.front();
     40         for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     41         {
     42             int y=t[i].y;
     43             if(dis[y]==-1)
     44             {
     45                 dis[y]=dis[x]+1;
     46                 q.push(y);
     47             }
     48         }
     49         q.pop();
     50     }
     51     if(dis[ed]==-1) return 0;
     52     return 1;
     53 }
     54 
     55 int ffind(int x,int flow)
     56 {
     57     if(x==ed) return flow;
     58     int now=0;
     59     for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     60     {
     61         int y=t[i].y;
     62         if(dis[y]==dis[x]+1)
     63         {
     64             int a=ffind(y,mymin(flow-now,t[i].f));
     65             t[i].f-=a;
     66             t[t[i].o].f+=a;
     67             now+=a;
     68         }
     69         if(now==flow) break;
     70     }
     71     if(now==0) dis[x]=-1;
     72     return now;
     73 }
     74 
     75 void output()
     76 {
     77     for(int i=1;i<=len;i+=2)
     78      printf("%d->%d %d
    ",t[i].x,t[i].y,t[i].f);
     79 }
     80 
     81 int max_flow()
     82 {
     83     int ans=0;
     84     while(bfs())
     85     {
     86         ans+=ffind(st,INF);
     87     }
     88     return ans;
     89 }
     90 
     91 int op[Maxn][Maxn];
     92 
     93 int main()
     94 {
     95     int k,n,m=0;
     96     scanf("%d%d",&k,&n);
     97     st=n+k+1;ed=st+1;
     98     len=0;
     99     memset(first,0,sizeof(first));
    100     for(int i=1;i<=k;i++)
    101     {
    102         int x;
    103         scanf("%d",&x);
    104         m+=x;
    105         ins(n+i,ed,x);
    106     }
    107     for(int i=1;i<=n;i++)
    108     {
    109         int x;
    110         scanf("%d",&x);
    111         ins(st,i,1);
    112         while(x--)
    113         {
    114             int y;
    115             scanf("%d",&y);
    116             ins(i,y+n,1);
    117         }
    118     }
    119     int now=max_flow();
    120     if(now<m) printf("No Solution!
    ");
    121     else
    122     {
    123         for(int i=1;i<=k;i++) op[i][0]=0;
    124         for(int i=1;i<=len;i+=2) if(t[i].x!=st&&t[i].y!=ed&&t[i].f==0)
    125         {
    126             op[t[i].y-n][++op[t[i].y-n][0]]=t[i].x;
    127         }
    128         for(int i=1;i<=k;i++)
    129         {
    130             printf("%d: ",i);
    131          for(int j=1;j<=op[i][0];j++)
    132             printf("%d ",op[i][j]);printf("
    ");
    133         }
    134     }
    135     return 0;
    136 }
    View Code

    没special judge 测不了 哭泣。。

    2016-11-04 14:53:36

  • 相关阅读:
    标准化:释放物联网全部潜力的万能钥匙
    Linux系统中如何删除交换文件,来解决突然关闭命令行,导致文件无法打开的问题
    echarts设置图例以及网络格局的相关细节设置
    JSON.parse()与JSON.stringify()的区别,具体例子,一看就明白
    HttpServletRequest
    HttpServletResponse
    JavaWeb核心之Servlet
    Http协议和Tomcat服务器
    dom4j解析
    DTD和Schema约束
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6030278.html
Copyright © 2011-2022 走看看