题目
https://www.luogu.org/problemnew/show/P3254
结题思路
跟试题库问题很像。//听所贪心也能过
【需要注意的是:因为跟试题库问题的建图有一些区别,所以在输出的时候还要
−
k
-k
−k.】
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int inf=1e6;
struct node{
int y,w,next;
}a[80001];
queue<int>que;
int k,n,m,s,t,ans,len=1,last[40001],dis[40001];
void add(int x,int y,int w)
{
a[++len]={y,w,last[x]}; last[x]=len;
a[++len]={x,0,last[y]}; last[y]=len;
}
bool bfs()
{
memset(dis,0,sizeof(dis));
while (!que.empty()) que.pop();
dis[s]=1; que.push(s);
while (!que.empty()){
int u=que.front(); que.pop();
for (int i=last[u];i;i=a[i].next)
if (a[i].w&&!dis[a[i].y]){
dis[a[i].y]=dis[u]+1;
if (a[i].y==t) return 1;
que.push(a[i].y);
}
}
return 0;
}
int dinic(int xq,int maxf)
{
if (xq==t||!maxf) return maxf;
int ret=0,f=0;
for (int i=last[xq];i;i=a[i].next)
if (a[i].w&&dis[a[i].y]==dis[xq]+1)
{
ret+=(f=dinic(a[i].y,min(a[i].w,maxf-ret)));
a[i].w-=f; a[i^1].w+=f;
if (maxf==ret) break;
}
return ret;
}
int main()
{
scanf("%d%d",&k,&n);
int g; s=k+n+1; t=s+1;
for (int i=1;i<=k;i++) scanf("%d",&g),m+=g,add(s,i,g);
for (int i=1;i<=n;i++)
{
scanf("%d",&g),add(k+i,t,g);
for (int j=1;j<=k;j++) add(j,k+i,1);
}
while (bfs()) ans+=dinic(s,inf);
if (ans==m){
printf("1\n");
for (int i=1;i<=k;printf("\n"),i++)
{
for (int j=last[i];j;j=a[j].next)
if (a[j].y<=k+n&&a[j].y>k&&!a[j].w) printf("%d ",a[j].y-k);
}
} else printf("0\n");
}