网络流24题之试题库问题

题意说的有问题啊。。。

应该是每种类型至少有p题,因为一道题可以向多个类型做贡献。

将源点向每题连流量为1的边,代表选一本

将每题向各种连流量为1的边,表示只能对其中一种有贡献

将每种向汇点连流量为需求的边。

记录答案第二种边判断即可

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1100,inf=1e9;
 4 int s=0,t=1050,cnt=-1,head[N],v[N],k,n,m;
 5 struct node{
 6     int to,nex,w;
 7 }e[100005];
 8 void add(int x,int y,int w)
 9 {
10     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;
11     e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;
12 }
13 queue<int>q;
14 bool bfs(int x,int y)
15 {
16     memset(v,-1,sizeof(v));
17     v[x]=0;q.push(x);
18     while(!q.empty())
19     {
20         int x=q.front();q.pop();
21         for(int i=head[x];i!=-1;i=e[i].nex)
22         {
23             int y=e[i].to;
24             if(v[y]!=-1||e[i].w==0)continue;
25             v[y]=v[x]+1;q.push(y);
26         }
27     }
28     return v[y]!=-1;
29 }
30 int dfs(int x,int w,int yy)
31 {
32     if(x==yy||!w)return w;
33     int s=0;
34     for(int i=head[x];i!=-1;i=e[i].nex)
35     {
36         int y=e[i].to;
37         if(v[y]!=v[x]+1||!e[i].w)continue;
38         int flow=dfs(y,min(w-s,e[i].w),yy);
39         if(!flow)v[y]=-1;
40         e[i].w-=flow;e[i^1].w+=flow;
41         s+=flow;
42         if(s==w)return s;
43     }
44     return s;
45 }
46 int dinic()
47 {
48     int ans=0;
49     while(bfs(s,t))
50     {
51         ans+=dfs(s,inf,t);
52     }
53     return ans;
54 }
55 int num[25],p[N],bel[N][N];
56 int main()
57 {
58     scanf("%d%d",&k,&n);
59     memset(head,-1,sizeof(head));
60     for(int i=1;i<=k;++i)
61     {
62         scanf("%d",&num[i]);
63         add(i+n,t,num[i]);
64     }
65     for(int i=1;i<=n;++i)
66     {
67         scanf("%d",&p[i]);
68         for(int j=1;j<=p[i];++j)
69         scanf("%d",&bel[i][j]),add(i,bel[i][j]+n,1);
70         add(s,i,1);
71     }
72     int ans=dinic();
73     if(ans<m){puts("No Solution!");return 0;}
74     for(int i=1;i<=k;++i)
75     {
76         printf("%d: ",i);
77         for(int j=head[i+n];j!=-1;j=e[j].nex)
78         {
79             int y=e[j].to;
80             if(!e[j].w)continue;
81             printf("%d ",y);
82         }
83         printf("\n");
84     }
85     return 0;
86 }

 

posted @ 2018-01-27 11:08  大奕哥&VANE  阅读(227)  评论(0编辑  收藏  举报